neo.mjs 5.12.4 → 5.12.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.
- package/apps/ServiceWorker.mjs +2 -2
- package/examples/ConfigurationViewport.mjs +3 -6
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/button/base/MainContainer.mjs +2 -0
- package/package.json +1 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/button/Base.mjs +21 -55
- package/src/component/Base.mjs +1 -0
- package/src/menu/List.mjs +71 -3
- package/src/table/View.mjs +122 -78
package/apps/ServiceWorker.mjs
CHANGED
@@ -69,17 +69,14 @@ class ConfigurationViewport extends Viewport {
|
|
69
69
|
items : [me.exampleComponent],
|
70
70
|
flex : me.exampleComponentFlex,
|
71
71
|
layout: 'base',
|
72
|
-
style : {padding: '20px'}
|
72
|
+
style : {overflow: 'auto', padding: '20px'},
|
73
|
+
...me.exampleContainerConfig
|
73
74
|
}, {
|
74
75
|
module: Panel,
|
75
76
|
cls : ['neo-panel', 'neo-container', 'neo-configuration-panel'],
|
76
77
|
flex : me.configPanelFlex,
|
77
78
|
style : {margin: '20px', minWidth: me.configPanelMinWidth},
|
78
79
|
|
79
|
-
containerConfig: {
|
80
|
-
style: {overflowY: 'scroll'}
|
81
|
-
},
|
82
|
-
|
83
80
|
headers: [{
|
84
81
|
dock : 'top',
|
85
82
|
style: {borderLeft:0, borderRight:0, borderTop:0},
|
@@ -100,7 +97,7 @@ class ConfigurationViewport extends Viewport {
|
|
100
97
|
items: [{
|
101
98
|
module: Container,
|
102
99
|
layout: {ntype: 'vbox'},
|
103
|
-
style : {padding: '10px'},
|
100
|
+
style : {overflowY: 'auto', padding: '10px'},
|
104
101
|
cls : ['neo-configuration-panel-body'],
|
105
102
|
itemDefaults: {
|
106
103
|
clearToOriginalValue: true,
|
@@ -177,9 +177,11 @@ class MainContainer extends ConfigurationViewport {
|
|
177
177
|
return Neo.create({
|
178
178
|
module : Button,
|
179
179
|
badgeText: 'Badge',
|
180
|
+
flex : 'none',
|
180
181
|
handler : data => console.log('button click =>', data.component.id),
|
181
182
|
height : 50,
|
182
183
|
iconCls : 'fa fa-home',
|
184
|
+
style : {marginBottom: '1500px', marginTop: '500px'},
|
183
185
|
text : 'Hello World',
|
184
186
|
ui : 'primary',
|
185
187
|
width : 150,
|
package/package.json
CHANGED
package/src/DefaultConfig.mjs
CHANGED
@@ -236,12 +236,12 @@ const DefaultConfig = {
|
|
236
236
|
useVdomWorker: true,
|
237
237
|
/**
|
238
238
|
* buildScripts/injectPackageVersion.mjs will update this value
|
239
|
-
* @default '5.12.
|
239
|
+
* @default '5.12.6'
|
240
240
|
* @memberOf! module:Neo
|
241
241
|
* @name config.version
|
242
242
|
* @type String
|
243
243
|
*/
|
244
|
-
version: '5.12.
|
244
|
+
version: '5.12.6'
|
245
245
|
};
|
246
246
|
|
247
247
|
Object.assign(DefaultConfig, {
|
package/src/button/Base.mjs
CHANGED
@@ -251,45 +251,15 @@ class Base extends Component {
|
|
251
251
|
let me = this;
|
252
252
|
|
253
253
|
me.menuList = Neo.create({
|
254
|
-
module
|
255
|
-
appName
|
256
|
-
displayField: 'text',
|
257
|
-
floating
|
258
|
-
hidden
|
259
|
-
items
|
260
|
-
|
261
|
-
});
|
262
|
-
|
263
|
-
me.vdom.cn.push(me.menuList.vdom)
|
264
|
-
})
|
265
|
-
}
|
266
|
-
}
|
267
|
-
|
268
|
-
/**
|
269
|
-
* Triggered after the mounted config got changed
|
270
|
-
* @param {Boolean} value
|
271
|
-
* @param {Boolean} oldValue
|
272
|
-
* @protected
|
273
|
-
*/
|
274
|
-
afterSetMounted(value, oldValue) {
|
275
|
-
super.afterSetMounted(value, oldValue);
|
276
|
-
|
277
|
-
let me = this,
|
278
|
-
style;
|
279
|
-
|
280
|
-
if (value && me.menu) {
|
281
|
-
setTimeout(() => {
|
282
|
-
me.getDomRect().then(rect => {
|
283
|
-
style = me.menuList.style || {};
|
284
|
-
|
285
|
-
Object.assign(style, {
|
286
|
-
right: 0,
|
287
|
-
top : rect.height + 'px'
|
288
|
-
});
|
289
|
-
|
290
|
-
me.menuList.style = style
|
254
|
+
module : module.default,
|
255
|
+
appName : me.appName,
|
256
|
+
displayField : 'text',
|
257
|
+
floating : true,
|
258
|
+
hidden : true,
|
259
|
+
items : value,
|
260
|
+
parentComponent: me
|
291
261
|
})
|
292
|
-
}
|
262
|
+
})
|
293
263
|
}
|
294
264
|
}
|
295
265
|
|
@@ -302,7 +272,7 @@ class Base extends Component {
|
|
302
272
|
afterSetPressed(value, oldValue) {
|
303
273
|
let cls = this.cls;
|
304
274
|
|
305
|
-
NeoArray
|
275
|
+
NeoArray.toggle(cls, 'pressed', value === true);
|
306
276
|
this.cls = cls;
|
307
277
|
}
|
308
278
|
|
@@ -314,18 +284,16 @@ class Base extends Component {
|
|
314
284
|
*/
|
315
285
|
afterSetText(value, oldValue) {
|
316
286
|
let me = this,
|
287
|
+
isEmpty = !value || value === '',
|
317
288
|
vdomRoot = me.getVdomRoot(),
|
318
289
|
textNode = vdomRoot.cn[1];
|
319
290
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
NeoArray.remove(vdomRoot.cls, 'no-text');
|
327
|
-
textNode.removeDom = false;
|
328
|
-
textNode.innerHTML = value;
|
291
|
+
NeoArray.toggle(me._cls, 'no-text', isEmpty);
|
292
|
+
NeoArray.toggle(vdomRoot.cls, 'no-text', isEmpty);
|
293
|
+
textNode.removeDom = isEmpty;
|
294
|
+
|
295
|
+
if (!isEmpty) {
|
296
|
+
textNode.innerHTML = value
|
329
297
|
}
|
330
298
|
|
331
299
|
me.update()
|
@@ -430,7 +398,7 @@ class Base extends Component {
|
|
430
398
|
* @protected
|
431
399
|
*/
|
432
400
|
beforeSetIconPosition(value, oldValue) {
|
433
|
-
return this.beforeSetEnumValue(value, oldValue, 'iconPosition')
|
401
|
+
return this.beforeSetEnumValue(value, oldValue, 'iconPosition')
|
434
402
|
}
|
435
403
|
|
436
404
|
/**
|
@@ -520,23 +488,21 @@ class Base extends Component {
|
|
520
488
|
rippleWrapper.removeDom = true;
|
521
489
|
me.update()
|
522
490
|
}
|
523
|
-
}, rippleEffectDuration)
|
491
|
+
}, rippleEffectDuration)
|
524
492
|
}
|
525
493
|
|
526
494
|
/**
|
527
495
|
*
|
528
496
|
*/
|
529
|
-
toggleMenu() {
|
497
|
+
async toggleMenu() {
|
530
498
|
let menuList = this.menuList,
|
531
499
|
hidden = !menuList.hidden;
|
532
500
|
|
533
501
|
menuList.hidden = hidden;
|
534
502
|
|
535
503
|
if (!hidden) {
|
536
|
-
|
537
|
-
|
538
|
-
menuList.focus()
|
539
|
-
}, 500)
|
504
|
+
await Neo.timeout(50);
|
505
|
+
menuList.focus()
|
540
506
|
}
|
541
507
|
}
|
542
508
|
}
|
package/src/component/Base.mjs
CHANGED
package/src/menu/List.mjs
CHANGED
@@ -39,6 +39,11 @@ class List extends BaseList {
|
|
39
39
|
* @protected
|
40
40
|
*/
|
41
41
|
focusTimeoutId: null,
|
42
|
+
/**
|
43
|
+
* Hides a floating list on leaf item click, in case it has a parentComponent
|
44
|
+
* @member {Boolean} hideOnLeafItemClick=true
|
45
|
+
*/
|
46
|
+
hideOnLeafItemClick: true,
|
42
47
|
/**
|
43
48
|
* Optionally pass menu.Store data directly
|
44
49
|
* @member {Object[]|null} items_=null
|
@@ -104,6 +109,12 @@ class List extends BaseList {
|
|
104
109
|
{tag: 'ul', tabIndex: -1, cn: []}
|
105
110
|
}
|
106
111
|
|
112
|
+
/**
|
113
|
+
* If the menu is floating, it will anchor itself to the parentRect
|
114
|
+
* @member {Neo.component.Base|null} parentComponent=null
|
115
|
+
*/
|
116
|
+
parentComponent = null
|
117
|
+
|
107
118
|
/**
|
108
119
|
* Triggered after the floating config got changed
|
109
120
|
* @param {Object[]} value
|
@@ -143,7 +154,6 @@ class List extends BaseList {
|
|
143
154
|
if (me.isRoot) {
|
144
155
|
if (!value) {
|
145
156
|
me.focusTimeoutId = setTimeout(() => {
|
146
|
-
console.log('unmount'); // todo: does not hide a top-level floating menu
|
147
157
|
me[me.floating ? 'unmount' : 'hideSubMenu']();
|
148
158
|
}, 20);
|
149
159
|
} else {
|
@@ -157,6 +167,43 @@ class List extends BaseList {
|
|
157
167
|
}
|
158
168
|
}
|
159
169
|
|
170
|
+
/**
|
171
|
+
* Triggered after the mounted config got changed
|
172
|
+
* @param {Boolean} value
|
173
|
+
* @param {Boolean} oldValue
|
174
|
+
* @protected
|
175
|
+
*/
|
176
|
+
afterSetMounted(value, oldValue) {
|
177
|
+
super.afterSetMounted(value, oldValue);
|
178
|
+
|
179
|
+
let me = this,
|
180
|
+
id = me.id,
|
181
|
+
parentId = me.parentComponent?.id;
|
182
|
+
|
183
|
+
if (parentId) {
|
184
|
+
if (value) {
|
185
|
+
Neo.main.addon.ScrollSync.register({
|
186
|
+
sourceId: parentId,
|
187
|
+
targetId: id
|
188
|
+
});
|
189
|
+
|
190
|
+
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
|
+
}
|
205
|
+
}
|
206
|
+
|
160
207
|
/**
|
161
208
|
* Triggered after the zIndex config got changed
|
162
209
|
* @param {Number} value
|
@@ -270,7 +317,22 @@ class List extends BaseList {
|
|
270
317
|
* @param {Object[]} data.oldPath
|
271
318
|
*/
|
272
319
|
onFocusLeave(data) {
|
273
|
-
|
320
|
+
let insideParent = false,
|
321
|
+
parentId = this.parentComponent?.id,
|
322
|
+
item;
|
323
|
+
|
324
|
+
if (parentId) {
|
325
|
+
for (item of data.oldPath) {
|
326
|
+
if (item.id === parentId) {
|
327
|
+
insideParent = true;
|
328
|
+
break;
|
329
|
+
}
|
330
|
+
}
|
331
|
+
}
|
332
|
+
|
333
|
+
if (!insideParent) {
|
334
|
+
this.menuFocus = false
|
335
|
+
}
|
274
336
|
}
|
275
337
|
|
276
338
|
/**
|
@@ -280,7 +342,13 @@ class List extends BaseList {
|
|
280
342
|
onItemClick(node, data) {
|
281
343
|
super.onItemClick(node, data);
|
282
344
|
|
283
|
-
|
345
|
+
let me = this;
|
346
|
+
|
347
|
+
data.record.handler?.call(me, data);
|
348
|
+
|
349
|
+
if (me.hideOnLeafItemClick && !data.record.items) {
|
350
|
+
me.unmount()
|
351
|
+
}
|
284
352
|
}
|
285
353
|
|
286
354
|
/**
|
package/src/table/View.mjs
CHANGED
@@ -45,6 +45,87 @@ class View extends Component {
|
|
45
45
|
{tag: 'tbody', cn: []}
|
46
46
|
}
|
47
47
|
|
48
|
+
/**
|
49
|
+
* @param {String} cellId
|
50
|
+
* @param {Object} column
|
51
|
+
* @param {Object} record
|
52
|
+
* @param {Number} index
|
53
|
+
* @param {Neo.table.Container} tableContainer
|
54
|
+
* @returns {Object}
|
55
|
+
*/
|
56
|
+
applyRendererOutput(cellId, column, record, index, tableContainer) {
|
57
|
+
let me = this,
|
58
|
+
cellCls = ['neo-table-cell'],
|
59
|
+
dataField = column.dataField,
|
60
|
+
fieldValue = record[dataField],
|
61
|
+
hasStore = tableContainer.store?.model, // todo: remove as soon as all tables use stores (examples table)
|
62
|
+
vdom = me.vdom,
|
63
|
+
cellConfig, rendererOutput;
|
64
|
+
|
65
|
+
if (fieldValue === undefined) {
|
66
|
+
fieldValue = ''
|
67
|
+
}
|
68
|
+
|
69
|
+
rendererOutput = column.renderer.call(column.rendererScope || tableContainer, {
|
70
|
+
dataField,
|
71
|
+
index,
|
72
|
+
record,
|
73
|
+
value: fieldValue
|
74
|
+
});
|
75
|
+
|
76
|
+
switch (Neo.typeOf(rendererOutput)) {
|
77
|
+
case 'Object': {
|
78
|
+
if (rendererOutput.cls && rendererOutput.html) {
|
79
|
+
cellCls.push(...rendererOutput.cls);
|
80
|
+
} else {
|
81
|
+
rendererOutput = [rendererOutput];
|
82
|
+
}
|
83
|
+
break;
|
84
|
+
}
|
85
|
+
case 'Number':
|
86
|
+
case 'String': {
|
87
|
+
rendererOutput = {
|
88
|
+
cls : cellCls,
|
89
|
+
html: rendererOutput?.toString()
|
90
|
+
};
|
91
|
+
break;
|
92
|
+
}
|
93
|
+
}
|
94
|
+
|
95
|
+
if (rendererOutput === null || rendererOutput === undefined) {
|
96
|
+
rendererOutput = ''
|
97
|
+
}
|
98
|
+
|
99
|
+
if (column.align !== 'left') {
|
100
|
+
cellCls.push('neo-' + column.align)
|
101
|
+
}
|
102
|
+
|
103
|
+
if (!cellId) {
|
104
|
+
// todo: remove the else part as soon as all tables use stores (examples table)
|
105
|
+
if (hasStore) {
|
106
|
+
cellId = me.getCellId(record, column.dataField)
|
107
|
+
} else {
|
108
|
+
cellId = vdom.cn[i]?.cn[j]?.id || Neo.getId('td')
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
cellConfig = {
|
113
|
+
tag : 'td',
|
114
|
+
id : cellId,
|
115
|
+
cls : cellCls,
|
116
|
+
style : rendererOutput.style || {},
|
117
|
+
tabIndex: '-1'
|
118
|
+
};
|
119
|
+
|
120
|
+
if (Neo.typeOf(rendererOutput) === 'Object') {
|
121
|
+
cellConfig.innerHTML = rendererOutput.html || ''
|
122
|
+
} else {
|
123
|
+
cellConfig.cn = rendererOutput
|
124
|
+
}
|
125
|
+
|
126
|
+
return cellConfig
|
127
|
+
}
|
128
|
+
|
48
129
|
/**
|
49
130
|
* @param {Array} inputData
|
50
131
|
*/
|
@@ -52,14 +133,13 @@ class View extends Component {
|
|
52
133
|
let me = this,
|
53
134
|
amountRows = inputData.length,
|
54
135
|
container = Neo.getComponent(me.parentId),
|
55
|
-
hasStore = container.store?.model, // todo: remove as soon as all tables use stores (examples table)
|
56
136
|
columns = container.items[0].items,
|
57
137
|
colCount = columns.length,
|
58
138
|
data = [],
|
59
139
|
i = 0,
|
60
140
|
vdom = me.vdom,
|
61
|
-
|
62
|
-
record,
|
141
|
+
config, column, dockLeftMargin, dockRightMargin, id, index, j,
|
142
|
+
record, selectedRows, trCls;
|
63
143
|
|
64
144
|
me.recordVnodeMap = {}; // remove old data
|
65
145
|
|
@@ -97,69 +177,8 @@ class View extends Component {
|
|
97
177
|
j = 0;
|
98
178
|
|
99
179
|
for (; j < colCount; j++) {
|
100
|
-
column
|
101
|
-
|
102
|
-
|
103
|
-
if (rendererValue === undefined) {
|
104
|
-
rendererValue = '';
|
105
|
-
}
|
106
|
-
|
107
|
-
rendererOutput = column.renderer.call(column.rendererScope || container, {
|
108
|
-
dataField: column.dataField,
|
109
|
-
index : i,
|
110
|
-
record,
|
111
|
-
value : rendererValue
|
112
|
-
});
|
113
|
-
|
114
|
-
if (!rendererOutput) {
|
115
|
-
rendererOutput = ''
|
116
|
-
}
|
117
|
-
|
118
|
-
cellCls = ['neo-table-cell'];
|
119
|
-
|
120
|
-
switch (Neo.typeOf(rendererOutput)) {
|
121
|
-
case 'Object': {
|
122
|
-
if (rendererOutput.cls && rendererOutput.html) {
|
123
|
-
cellCls.push(...rendererOutput.cls);
|
124
|
-
} else {
|
125
|
-
rendererOutput = [rendererOutput];
|
126
|
-
}
|
127
|
-
break;
|
128
|
-
}
|
129
|
-
case 'Number':
|
130
|
-
case 'String': {
|
131
|
-
rendererOutput = {
|
132
|
-
cls : cellCls,
|
133
|
-
html: rendererOutput?.toString()
|
134
|
-
};
|
135
|
-
break;
|
136
|
-
}
|
137
|
-
}
|
138
|
-
|
139
|
-
if (column.align !== 'left') {
|
140
|
-
cellCls.push('neo-' + column.align)
|
141
|
-
}
|
142
|
-
|
143
|
-
// todo: remove the else part as soon as all tables use stores (examples table)
|
144
|
-
if (hasStore) {
|
145
|
-
cellId = me.getCellId(record, column.dataField);
|
146
|
-
} else {
|
147
|
-
cellId = vdom.cn[i]?.cn[j]?.id || Neo.getId('td');
|
148
|
-
}
|
149
|
-
|
150
|
-
config = {
|
151
|
-
tag : 'td',
|
152
|
-
id : cellId,
|
153
|
-
cls : cellCls,
|
154
|
-
style : rendererOutput.style || {},
|
155
|
-
tabIndex: '-1'
|
156
|
-
};
|
157
|
-
|
158
|
-
if (Neo.typeOf(rendererOutput) === 'Object') {
|
159
|
-
config.innerHTML = rendererOutput.html || ''
|
160
|
-
} else {
|
161
|
-
config.cn = rendererOutput
|
162
|
-
}
|
180
|
+
column = columns[j];
|
181
|
+
config = me.applyRendererOutput(null, column, record, i, container);
|
163
182
|
|
164
183
|
if (column.dock) {
|
165
184
|
config.cls = ['neo-locked', ...config.cls || []];
|
@@ -200,7 +219,7 @@ class View extends Component {
|
|
200
219
|
// this logic only works for selection.table.RowModel
|
201
220
|
Neo.main.DomAccess.scrollToTableRow({id: selectedRows[0]});
|
202
221
|
}
|
203
|
-
})
|
222
|
+
})
|
204
223
|
}
|
205
224
|
|
206
225
|
/**
|
@@ -221,6 +240,29 @@ class View extends Component {
|
|
221
240
|
return this.id + '__' + record[this.store.keyProperty] + '__' + dataField;
|
222
241
|
}
|
223
242
|
|
243
|
+
/**
|
244
|
+
* Get a table column by a given field name
|
245
|
+
* @param {String} field
|
246
|
+
* @returns {Object|null}
|
247
|
+
*/
|
248
|
+
getColumn(field) {
|
249
|
+
let container = Neo.getComponent(this.parentId),
|
250
|
+
columns = container.columns,
|
251
|
+
i = 0,
|
252
|
+
len = columns.length,
|
253
|
+
column;
|
254
|
+
|
255
|
+
for (; i < len; i++) {
|
256
|
+
column = columns[i];
|
257
|
+
|
258
|
+
if (column.dataField === field) {
|
259
|
+
return column
|
260
|
+
}
|
261
|
+
}
|
262
|
+
|
263
|
+
return null
|
264
|
+
}
|
265
|
+
|
224
266
|
/**
|
225
267
|
* Get the matching record by passing a row id, a cell id or an id inside a table cell.
|
226
268
|
* @param {String} nodeId
|
@@ -292,26 +334,28 @@ class View extends Component {
|
|
292
334
|
* @param {Object} opts.record
|
293
335
|
*/
|
294
336
|
onStoreRecordChange(opts) {
|
295
|
-
let me
|
296
|
-
|
297
|
-
|
337
|
+
let me = this,
|
338
|
+
container = Neo.getComponent(me.parentId),
|
339
|
+
needsUpdate = false,
|
340
|
+
vdom = me.vdom,
|
341
|
+
cellId, cellNode, column, index, scope;
|
298
342
|
|
299
343
|
opts.fields.forEach(field => {
|
300
344
|
cellId = me.getCellId(opts.record, field.name);
|
301
|
-
cellNode =
|
345
|
+
cellNode = VDomUtil.findVdomChild(vdom, cellId);
|
302
346
|
|
303
347
|
// the vdom might not exist yet => nothing to do in this case
|
304
|
-
if (cellNode) {
|
305
|
-
|
348
|
+
if (cellNode?.vdom) {
|
349
|
+
column = me.getColumn(field.name);
|
350
|
+
index = cellNode.index;
|
351
|
+
needsUpdate = true;
|
352
|
+
scope = column.rendererScope || container;
|
306
353
|
|
307
|
-
|
308
|
-
id : cellId,
|
309
|
-
innerHTML: field.value
|
310
|
-
})
|
354
|
+
cellNode.parentNode.cn[index] = me.applyRendererOutput(cellId, column, opts.record, index, container)
|
311
355
|
}
|
312
356
|
});
|
313
357
|
|
314
|
-
|
358
|
+
needsUpdate && me.update()
|
315
359
|
}
|
316
360
|
}
|
317
361
|
|