neo.mjs 6.7.5 → 6.7.6

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.
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='6.7.5'
23
+ * @member {String} version='6.7.6'
24
24
  */
25
- version: '6.7.5'
25
+ version: '6.7.6'
26
26
  }
27
27
 
28
28
  /**
@@ -121,7 +121,7 @@ class Table extends Container {
121
121
  if (oldValue !== undefined) {
122
122
  let me = this,
123
123
  selectionModel = me.selectionModel,
124
- view = me.getView(),
124
+ view = me.view,
125
125
  id;
126
126
 
127
127
  if (view) {
@@ -158,7 +158,7 @@ class Table extends Container {
158
158
 
159
159
  if (me.store.getCount() > 0) {
160
160
  if (item) {
161
- item = me.getView().getRecordByRowId(item)?.country;
161
+ item = me.view.getRecordByRowId(item)?.country;
162
162
  }
163
163
 
164
164
  // in case getRecordByRowId() has no match, the initial row creation will include the selection
@@ -124,7 +124,7 @@ class Table extends Container {
124
124
  id;
125
125
 
126
126
  if (value) {
127
- id = `${me.getView().id}__tr__${value}`; // the store can not be loaded on the first selection
127
+ id = `${me.view.id}__tr__${value}`; // the store can not be loaded on the first selection
128
128
 
129
129
  if (!selectionModel.isSelected(id)) {
130
130
  selectionModel.select(id);
@@ -155,7 +155,7 @@ class Table extends Container {
155
155
 
156
156
  if (me.store.getCount() > 0) {
157
157
  if (item) {
158
- item = me.getView().getRecordByRowId(item)?.country;
158
+ item = me.view.getRecordByRowId(item)?.country;
159
159
  }
160
160
 
161
161
  // in case getRecordByRowId() has no match, the initial row creation will include the selection
@@ -20,9 +20,9 @@ class ServiceWorker extends ServiceBase {
20
20
  */
21
21
  singleton: true,
22
22
  /**
23
- * @member {String} version='6.7.5'
23
+ * @member {String} version='6.7.6'
24
24
  */
25
- version: '6.7.5'
25
+ version: '6.7.6'
26
26
  }
27
27
 
28
28
  /**
@@ -8,10 +8,41 @@ import SelectField from '../../src/form/field/Select.mjs';
8
8
  */
9
9
  class DemoDialog extends Dialog {
10
10
  static config = {
11
- className: 'Neo.examples.dialog.DemoWindow',
12
- modal : true,
13
- title : 'My Dialog',
14
-
11
+ /**
12
+ * @member {String} className='Neo.examples.dialog.DemoDialog'
13
+ * @protected
14
+ */
15
+ className: 'Neo.examples.dialog.DemoDialog',
16
+ /**
17
+ * Custom config to dynamically enable / disable the animateTargetId
18
+ * @member {Boolean} animated_=true
19
+ */
20
+ animated_: true,
21
+ /**
22
+ * @member {Object} containerConfig
23
+ */
24
+ containerConfig: {
25
+ style: {
26
+ padding: '1em'
27
+ }
28
+ },
29
+ /**
30
+ * Custom config to show the current dialog number
31
+ * @member {Number} index=1
32
+ */
33
+ index: 1,
34
+ /**
35
+ * @member {Boolean} modal=true
36
+ */
37
+ modal: true,
38
+ /**
39
+ * Custom config used by animated_
40
+ * @member {String|null} optionalAnimateTargetId=null
41
+ */
42
+ optionalAnimateTargetId: null,
43
+ /**
44
+ * @member {Object} wrapperStyle
45
+ */
15
46
  wrapperStyle: {
16
47
  width : '40%'
17
48
  }
@@ -26,8 +57,9 @@ class DemoDialog extends Dialog {
26
57
  const me = this;
27
58
 
28
59
  me.items = [{
29
- module : SelectField,
30
- labelText: 'Select',
60
+ module : SelectField,
61
+ labelText : 'Select',
62
+ labelWidth: 80,
31
63
 
32
64
  store: {
33
65
  data: (() => {
@@ -37,43 +69,90 @@ class DemoDialog extends Dialog {
37
69
  result.push({
38
70
  id : i,
39
71
  name : `Option ${i + 1}`
40
- });
72
+ })
41
73
  }
42
74
 
43
- return result;
75
+ return result
44
76
  })()
45
77
  }
46
78
  }, {
47
79
  module : Button,
48
80
  handler : me.createDialog.bind(me),
49
81
  iconCls : 'fa fa-window-maximize',
50
- reference: 'create-second-dialog-button',
51
- text : 'Create new modal Dialog',
82
+ reference: 'create-dialog-button',
83
+ style : {marginTop: '3em'},
84
+ text : 'Create Dialog ' + (me.index + 1),
52
85
  }]
53
86
  }
54
87
 
88
+ /**
89
+ * Triggered after the animated config got changed
90
+ * @param {Boolean} value
91
+ * @param {Boolean} oldValue
92
+ * @protected
93
+ */
94
+ afterSetAnimated(value, oldValue) {
95
+ let me = this;
96
+
97
+ me.animateTargetId = value ? me.optionalAnimateTargetId : null;
98
+
99
+ if (me.dialog) {
100
+ me.dialog.animated = value
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Triggered after the modal config got changed
106
+ * @param {Boolean} value
107
+ * @param {Boolean} oldValue
108
+ * @protected
109
+ */
110
+ afterSetModal(value, oldValue) {
111
+ super.afterSetModal(value, oldValue);
112
+
113
+ if (this.dialog) {
114
+ this.dialog.modal = value
115
+ }
116
+ }
117
+
55
118
  /**
56
119
  * @param {Object} data
57
120
  */
58
121
  createDialog(data) {
59
- let me = this;
122
+ let me = this,
123
+ button = data.component,
124
+ nextIndex = me.index + 1;
60
125
 
61
- data.component.disabled = true;
126
+ button.disabled = true;
62
127
 
63
128
  me.dialog = Neo.create(DemoDialog, {
64
- appName : me.appName,
65
- boundaryContainerId: me.boundaryContainerId,
66
- listeners : {close: me.onWindowClose, scope: me},
67
- modal : true,
68
- title : 'Second Dialog'
69
- });
129
+ animated : me.animated,
130
+ appName : me.appName,
131
+ boundaryContainerId : me.boundaryContainerId,
132
+ index : nextIndex,
133
+ listeners : {close: me.onWindowClose, scope: me},
134
+ modal : me.app.mainView.down({valueLabelText: 'Modal'}).checked,
135
+ optionalAnimateTargetId: button.id,
136
+ style : {left: me.getOffset(), top: me.getOffset()},
137
+ title : 'Dialog ' + nextIndex
138
+ })
139
+ }
140
+
141
+ /**
142
+ * We want new dialogs to have a random left & top offset between -100px & 100px,
143
+ * to ensure they are not at the exact same position.
144
+ * @returns {String}
145
+ */
146
+ getOffset() {
147
+ let offset = Math.floor(Math.random() * 200 - 100);
148
+ return `calc(50% + ${offset}px)`
70
149
  }
71
150
 
72
151
  /**
73
152
  *
74
153
  */
75
154
  onWindowClose() {
76
- this.getReference('create-second-dialog-button').disabled = false;
155
+ this.getReference('create-dialog-button').disabled = false
77
156
  }
78
157
  }
79
158
 
@@ -38,16 +38,17 @@ class MainContainer extends Viewport {
38
38
  me.items = [{
39
39
  module: Toolbar,
40
40
  items :[{
41
- module : Button,
42
- handler: me.createDialog.bind(me),
43
- iconCls: 'fa fa-window-maximize',
44
- text : 'Create Dialog',
41
+ module : Button,
42
+ handler : me.createDialog.bind(me),
43
+ iconCls : 'fa fa-window-maximize',
44
+ reference: 'create-dialog-button',
45
+ text : 'Create Dialog',
45
46
  }, {
46
47
  module : CheckBox,
47
48
  checked : true,
48
49
  hideLabel : true,
49
50
  hideValueLabel: false,
50
- listeners : {change: me.onDragLimitChange, scope: me},
51
+ listeners : {change: me.onConfigChange.bind(me, 'boundaryContainerId')},
51
52
  style : {marginLeft: '3em'},
52
53
  valueLabelText: 'Limit Drag&Drop to the document.body'
53
54
  }, {
@@ -55,7 +56,16 @@ class MainContainer extends Viewport {
55
56
  checked : true,
56
57
  hideLabel : true,
57
58
  hideValueLabel: false,
59
+ listeners : {change: me.onConfigChange.bind(me, 'animated')},
58
60
  style : {marginLeft: '3em'},
61
+ valueLabelText: 'Animated'
62
+ }, {
63
+ module : CheckBox,
64
+ checked : true,
65
+ hideLabel : true,
66
+ hideValueLabel: false,
67
+ listeners : {change: me.onConfigChange.bind(me, 'modal')},
68
+ style : {marginLeft: '1em'},
59
69
  valueLabelText: 'Modal'
60
70
  }, '->', {
61
71
  module : Button,
@@ -75,30 +85,31 @@ class MainContainer extends Viewport {
75
85
  data.component.disabled = true;
76
86
 
77
87
  me.dialog = Neo.create(DemoDialog, {
78
- animateTargetId : data.component.id,
79
- appName : me.appName,
80
- boundaryContainerId: me.boundaryContainerId,
81
- listeners : {close: me.onWindowClose, scope: me},
82
- modal : me.down({ valueLabelText : 'Modal' }).checked
83
- });
88
+ animated : me.down({valueLabelText: 'Animated'}).checked,
89
+ appName : me.appName,
90
+ boundaryContainerId : me.boundaryContainerId,
91
+ listeners : {close: me.onWindowClose, scope: me},
92
+ modal : me.down({valueLabelText: 'Modal'}).checked,
93
+ optionalAnimateTargetId: data.component.id,
94
+ title : 'Dialog 1'
95
+ })
84
96
  }
85
97
 
86
98
  /**
87
- * @param {Object} data
99
+ * @param {String} config
100
+ * @param {Object} opts
88
101
  */
89
- onDragLimitChange(data) {
90
- this.dialog.boundaryContainerId = data.value ? 'document.body' : null
102
+ onConfigChange(config, opts) {
103
+ if (this.dialog) {
104
+ this.dialog[config] = opts.value ? 'document.body' : null
105
+ }
91
106
  }
92
107
 
93
108
  /**
94
109
  *
95
110
  */
96
111
  onWindowClose() {
97
- let button = this.down({
98
- text: 'Create Dialog'
99
- });
100
-
101
- button.disabled = false;
112
+ this.getReference('create-dialog-button').disabled = false
102
113
  }
103
114
 
104
115
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "6.7.5",
3
+ "version": "6.7.6",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -39,6 +39,12 @@
39
39
  transition-timing-function: ease-out;
40
40
  }
41
41
 
42
+ &.neo-dragproxy {
43
+ > * {
44
+ height: fit-content;
45
+ }
46
+ }
47
+
42
48
  &.neo-maximized {
43
49
  height : 98% !important;
44
50
  left : 1% !important;
@@ -14,12 +14,12 @@
14
14
  }
15
15
 
16
16
  > * {
17
- height : 100% !important;
18
- left : 0 !important;
19
- position : relative !important;
20
- opacity : 1 !important;
21
- top : 0 !important;
22
- transform: none !important;
23
- width : 100% !important;
17
+ height : 100%;
18
+ left : 0;
19
+ position : relative;
20
+ opacity : 1;
21
+ top : 0;
22
+ transform: none;
23
+ width : 100%;
24
24
  }
25
- }
25
+ }
@@ -236,12 +236,12 @@ const DefaultConfig = {
236
236
  useVdomWorker: true,
237
237
  /**
238
238
  * buildScripts/injectPackageVersion.mjs will update this value
239
- * @default '6.7.5'
239
+ * @default '6.7.6'
240
240
  * @memberOf! module:Neo
241
241
  * @name config.version
242
242
  * @type String
243
243
  */
244
- version: '6.7.5'
244
+ version: '6.7.6'
245
245
  };
246
246
 
247
247
  Object.assign(DefaultConfig, {
@@ -136,11 +136,21 @@ class Base extends Panel {
136
136
  construct(config) {
137
137
  super.construct(config);
138
138
 
139
- let me = this;
139
+ let me = this,
140
+ style = me.style;
140
141
 
141
142
  me.createHeader();
142
143
 
143
- me.autoShow && me.show()
144
+ if (!me.animateTargetId) {
145
+ Neo.assignDefaults(style, {
146
+ left : '50%',
147
+ top : '50%',
148
+ transform: 'translate(-50%, -50%)',
149
+ width : '50%'
150
+ });
151
+
152
+ me.style = style
153
+ }
144
154
  }
145
155
 
146
156
  /**
@@ -224,7 +234,7 @@ class Base extends Panel {
224
234
  cls = me.vdom.cls; // todo: using wrapperCls
225
235
 
226
236
  NeoArray.toggle(cls, 'neo-maximized', value);
227
- me.update();
237
+ me.update()
228
238
  }
229
239
 
230
240
  /**
@@ -234,16 +244,12 @@ class Base extends Panel {
234
244
  * @protected
235
245
  */
236
246
  afterSetModal(value, oldValue) {
237
- const
238
- me = this,
239
- { cls } = me.vdom;
247
+ let me = this;
240
248
 
241
- NeoArray.toggle(cls, 'neo-modal', value);
249
+ NeoArray.toggle(me.vdom.cls, 'neo-modal', value);
242
250
  me.update();
243
251
 
244
- if (me.rendered) {
245
- me.syncModalMask()
246
- }
252
+ me.rendered && me.syncModalMask()
247
253
  }
248
254
 
249
255
  /**
@@ -322,10 +328,12 @@ class Base extends Panel {
322
328
 
323
329
  me.closeOrHide(false);
324
330
 
325
- await Neo.applyDeltas(appName, [
326
- {id, cls: {remove: ['animated-hiding-showing']}},
327
- {id, action: 'removeNode'}
328
- ])
331
+ if (me.closeAction === 'hide') {
332
+ await Neo.applyDeltas(appName, [
333
+ {id, cls: {remove: ['animated-hiding-showing']}},
334
+ {id, action: 'removeNode'}
335
+ ])
336
+ }
329
337
  }
330
338
 
331
339
  /**
@@ -360,7 +368,7 @@ class Base extends Panel {
360
368
  add: ['animated-hiding-showing']
361
369
  },
362
370
  style: {
363
- height : style?.height || '',
371
+ height : style?.height || null, // height will point to the animation origin, so we need a reset
364
372
  left : style?.left || '50%',
365
373
  top : style?.top || '50%',
366
374
  transform: style?.transform || 'translate(-50%, -50%)',
@@ -404,13 +412,20 @@ class Base extends Panel {
404
412
  * @param {Boolean} animate=!!this.animateTargetId
405
413
  */
406
414
  async closeOrHide(animate=!!this.animateTargetId) {
407
- const
408
- me = this,
409
- { id } = me;
415
+ let me = this;
410
416
 
411
417
  me[me.closeAction](animate);
412
418
  await me.timeout(30);
413
- me.syncModalMask(id)
419
+ me.syncModalMask(me.id)
420
+ }
421
+
422
+ /**
423
+ * Action when clicking the X button inside the header toolbar.
424
+ * @param {Object} data
425
+ * @protected
426
+ */
427
+ closeOrHideAction(data) {
428
+ this.closeOrHide()
414
429
  }
415
430
 
416
431
  /**
@@ -447,7 +462,7 @@ class Base extends Panel {
447
462
  let me = this,
448
463
 
449
464
  map = {
450
- close : me.closeOrHide,
465
+ close : me.closeOrHideAction,
451
466
  maximize: me.maximize
452
467
  };
453
468
 
@@ -500,6 +515,23 @@ class Base extends Panel {
500
515
  me.syncModalMask()
501
516
  }
502
517
 
518
+ /**
519
+ *
520
+ */
521
+ init() {
522
+ super.init();
523
+
524
+ let me = this;
525
+
526
+ if (me.animateTargetId) {
527
+ me.autoShow && me.show()
528
+ } else {
529
+ me.timeout(100).then(() => {
530
+ me.syncModalMask()
531
+ })
532
+ }
533
+ }
534
+
503
535
  /**
504
536
  * @param {Object} [data]
505
537
  */
@@ -642,7 +674,7 @@ class Base extends Panel {
642
674
  */
643
675
  syncModalMask(id=this.id) {
644
676
  // This should sync the visibility and position of the modal mask element.
645
- Neo.main.DomAccess.syncModalMask({ id, modal: this.modal });
677
+ Neo.main.DomAccess.syncModalMask({ id, modal: this.modal })
646
678
  }
647
679
  }
648
680
 
@@ -390,6 +390,10 @@ class DomAccess extends Base {
390
390
  return returnData
391
391
  }
392
392
 
393
+ /**
394
+ * @param {Object|String} data
395
+ * @returns {Neo.util.Rectangle}
396
+ */
393
397
  getClippedRect(data) {
394
398
  let node = this.getElement(typeof data === 'object' ? data.id : data),
395
399
  { defaultView } = node.ownerDocument,
@@ -404,21 +408,6 @@ class DomAccess extends Base {
404
408
  return rect
405
409
  }
406
410
 
407
- onDocumentMutation(mutations) {
408
- const me = this;
409
-
410
- // If the mutations are purely align subjects being added or removed, take no action.
411
- if (!mutations.every(({ type, addedNodes, removedNodes }) => {
412
- if (type === 'childList') {
413
- const nodes = [...Array.from(addedNodes), ...Array.from(removedNodes)];
414
-
415
- return nodes.every(a => me.isAlignSubject(a))
416
- }
417
- })) {
418
- me.syncAligns();
419
- }
420
- }
421
-
422
411
  /**
423
412
  * @param {String|HTMLElement} nodeId
424
413
  * @returns {HTMLElement}
@@ -537,6 +526,24 @@ class DomAccess extends Base {
537
526
  return value;
538
527
  }
539
528
 
529
+ /**
530
+ * @param {Array} mutations
531
+ */
532
+ onDocumentMutation(mutations) {
533
+ const me = this;
534
+
535
+ // If the mutations are purely align subjects being added or removed, take no action.
536
+ if (!mutations.every(({ type, addedNodes, removedNodes }) => {
537
+ if (type === 'childList') {
538
+ const nodes = [...Array.from(addedNodes), ...Array.from(removedNodes)];
539
+
540
+ return nodes.every(a => me.isAlignSubject(a))
541
+ }
542
+ })) {
543
+ me.syncAligns();
544
+ }
545
+ }
546
+
540
547
  /**
541
548
  *
542
549
  */
@@ -548,6 +555,7 @@ class DomAccess extends Base {
548
555
 
549
556
  /**
550
557
  * @param {Object} data
558
+ * @param {String} data.id
551
559
  * @param {String} data.nodeId
552
560
  */
553
561
  onGetOffscreenCanvas(data) {
@@ -627,7 +635,7 @@ class DomAccess extends Base {
627
635
  data,
628
636
  replyId: data.id,
629
637
  success: true
630
- });
638
+ })
631
639
  }
632
640
 
633
641
  /**
@@ -636,7 +644,7 @@ class DomAccess extends Base {
636
644
  */
637
645
  read(data) {
638
646
  if (typeof data === 'function') {
639
- data();
647
+ data()
640
648
  }
641
649
  }
642
650
 
@@ -836,6 +844,11 @@ class DomAccess extends Base {
836
844
  })
837
845
  }
838
846
 
847
+ /**
848
+ * @param {Object} data
849
+ * @param {String} data.id
850
+ * @param {Boolean} data.modal
851
+ */
839
852
  syncModalMask({ id, modal }) {
840
853
  const el = id && this.getElement(id);
841
854
 
@@ -843,7 +856,7 @@ class DomAccess extends Base {
843
856
  if (el && modal && el.ownerDocument.contains(el) && el.ownerDocument.defaultView.getComputedStyle(el).getPropertyValue('display') !== 'none') {
844
857
  document.body.insertBefore(this.modalMask, el);
845
858
  }
846
- // Otherwise, the mask needs to be blow the next topmost modal dialog if possible, or hidden
859
+ // Otherwise, the mask needs to be below the next topmost modal dialog if possible, or hidden
847
860
  else {
848
861
  const
849
862
  modals = document.querySelectorAll('.neo-modal'),
@@ -851,9 +864,8 @@ class DomAccess extends Base {
851
864
 
852
865
  // Move the mask under the next topmost modal now modal "id" is gone.
853
866
  if (topmostModal) {
854
- this.syncModalMask({ id : topmostModal.id, modal : true })
855
- }
856
- else {
867
+ this.syncModalMask({ id: topmostModal.id, modal: true })
868
+ } else {
857
869
  this._modalMask?.remove()
858
870
  }
859
871
  }
@@ -200,8 +200,8 @@ class App extends Base {
200
200
  }
201
201
 
202
202
  return import(
203
- /* webpackInclude: /[\\\/]app.mjs$/ */
204
- /* webpackExclude: /[\\\/]node_modules/ */
203
+ /* webpackInclude: /(?:\/|\\)app.mjs$/ */
204
+ /* webpackExclude: /(?:\/|\\)node_modules/ */
205
205
  /* webpackMode: "lazy" */
206
206
  `../../${path}.mjs`
207
207
  )