neo.mjs 5.10.13 → 5.11.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 (40) hide show
  1. package/apps/ServiceWorker.mjs +2 -2
  2. package/examples/ServiceWorker.mjs +2 -2
  3. package/examples/component/dateSelector/MainContainer.mjs +36 -22
  4. package/examples/component/timer/MainContainer.mjs +71 -0
  5. package/examples/component/timer/MainContainerController.mjs +95 -0
  6. package/examples/component/timer/app.mjs +7 -0
  7. package/examples/component/timer/index.html +12 -0
  8. package/examples/component/timer/neo-config.json +7 -0
  9. package/examples/component/video/MainContainer.mjs +46 -0
  10. package/examples/component/video/MainContainerController.mjs +37 -0
  11. package/examples/component/video/app.mjs +7 -0
  12. package/examples/component/video/index.html +12 -0
  13. package/examples/component/video/neo-config.json +7 -0
  14. package/examples/layout/form/MainContainer.mjs +131 -0
  15. package/examples/layout/form/app.mjs +6 -0
  16. package/examples/layout/form/index.html +11 -0
  17. package/examples/layout/form/neo-config.json +6 -0
  18. package/examples/list/base/MainModel.mjs +3 -0
  19. package/examples/list/base/MainStore.mjs +6 -0
  20. package/examples/table/container/MainContainer.mjs +6 -0
  21. package/package.json +4 -4
  22. package/resources/scss/src/component/Timer.scss +115 -0
  23. package/resources/scss/src/component/Video.scss +31 -0
  24. package/resources/scss/src/layout/Form.scss +27 -0
  25. package/resources/scss/theme-dark/component/Timer.scss +14 -0
  26. package/resources/scss/theme-dark/component/Video.scss +11 -0
  27. package/resources/scss/theme-light/component/Timer.scss +15 -0
  28. package/resources/scss/theme-light/component/Video.scss +11 -0
  29. package/src/DefaultConfig.mjs +2 -2
  30. package/src/component/DateSelector.mjs +44 -10
  31. package/src/component/Timer.mjs +328 -0
  32. package/src/component/Video.mjs +165 -0
  33. package/src/form/field/Date.mjs +42 -0
  34. package/src/layout/Flexbox.mjs +21 -0
  35. package/src/layout/Form.mjs +140 -0
  36. package/src/list/Base.mjs +11 -1
  37. package/src/selection/ListModel.mjs +3 -1
  38. package/src/table/Container.mjs +17 -0
  39. package/src/table/header/Button.mjs +36 -9
  40. package/src/table/header/Toolbar.mjs +26 -1
@@ -0,0 +1,140 @@
1
+ import Base from './Base.mjs';
2
+ import NeoArray from '../util/Array.mjs';
3
+
4
+ /**
5
+ * @class Neo.layout.Form
6
+ * @extends Neo.layout.Base
7
+ */
8
+ class Form extends Base {
9
+ static config = {
10
+ /**
11
+ * @member {String} className='Neo.layout.Form'
12
+ * @protected
13
+ */
14
+ className: 'Neo.layout.Form',
15
+ /**
16
+ * @member {String} ntype='layout-form'
17
+ * @protected
18
+ */
19
+ ntype: 'layout-form',
20
+ /**
21
+ * flex css allows gap. This adds it to the component style
22
+ * @member {String} gap_=null
23
+ */
24
+ gap_: null,
25
+ /**
26
+ * CSS className prefix
27
+ * @member {String} prefix='neo-form-'
28
+ */
29
+ prefix: 'neo-layout-form-'
30
+ }
31
+
32
+ /**
33
+ * Updates the Container style to add a gap to display:flex
34
+ * @param {String|null} value
35
+ * @param {String|null} oldValue
36
+ * @protected
37
+ */
38
+ afterSetGap(value, oldValue) {
39
+ if (!value && !oldValue) return;
40
+
41
+ let item = Neo.getComponent(this.containerId),
42
+ style = item.wrapperStyle;
43
+
44
+ style.gap = value;
45
+ item.wrapperStyle = style;
46
+ }
47
+
48
+ /**
49
+ * Applies the flex value to an item of the container this layout is bound to
50
+ * @param {Neo.component.Base} item
51
+ * @param {Number} index
52
+ */
53
+ applyChildAttributes(child, index) {
54
+ if (!child.ignoreLayout) {
55
+ if (child.ntype === 'fieldset') {
56
+ child.wrapperCls = NeoArray.union(child.wrapperCls, 'neo-layout-form-subfieldset');
57
+ } else if (child.ntype === 'legend') {
58
+ child.wrapperCls = NeoArray.union(child.wrapperCls, 'neo-layout-form-legend');
59
+ } else {
60
+ child.wrapperCls = NeoArray.union(child.wrapperCls, 'neo-layout-form-item');
61
+ }
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Applies CSS classes to the container this layout is bound to
67
+ */
68
+ applyRenderAttributes() {
69
+ let me = this,
70
+ container = Neo.getComponent(me.containerId),
71
+ wrapperCls = container?.wrapperCls || [];
72
+
73
+ if (!container) {
74
+ Neo.logError('layout.Form: applyRenderAttributes -> container not yet created', me.containerId);
75
+ }
76
+
77
+ NeoArray.add(wrapperCls, 'neo-layout-form');
78
+
79
+ container.wrapperCls = wrapperCls;
80
+ }
81
+
82
+ /**
83
+ * Removes all CSS rules from an container item this layout is bound to.
84
+ * Gets called when switching to a different layout.
85
+ * @param {Neo.component.Base} item
86
+ * @protected
87
+ */
88
+ removeChildAttributes(item) {
89
+ let style = item.wrapperStyle || {};
90
+
91
+ style.flex = item.flex || null;
92
+ item.wrapperStyle = style;
93
+ }
94
+
95
+ /**
96
+ * Removes all CSS rules from the container this layout is bound to.
97
+ * Gets called when switching to a different layout.
98
+ */
99
+ removeRenderAttributes() {
100
+ let me = this,
101
+ container = Neo.getComponent(me.containerId),
102
+ wrapperCls = container?.wrapperCls || [];
103
+
104
+ if (!container) {
105
+ Neo.logError('layout.Form: removeRenderAttributes -> container not yet created', me.containerId);
106
+ }
107
+
108
+ NeoArray.remove(wrapperCls, 'neo-layout-form');
109
+
110
+ container.wrapperCls = wrapperCls;
111
+ }
112
+
113
+ /**
114
+ * Updates the Container CSS wrapperCls
115
+ * @param {String|null} value
116
+ * @param {String|null} oldValue
117
+ * @param {String} propertyName
118
+ * @protected
119
+ */
120
+ updateInputValue(value, oldValue, propertyName) {
121
+ let me = this,
122
+ container = Neo.getComponent(me.containerId),
123
+ prefix = me.prefix,
124
+ wrapperCls = container?.wrapperCls;
125
+
126
+ if (container?.rendered) {
127
+ NeoArray.remove(wrapperCls, prefix + propertyName + '-' + oldValue);
128
+
129
+ if (value !== null) {
130
+ NeoArray.add(wrapperCls, prefix + propertyName + '-' + value);
131
+ }
132
+
133
+ container.wrapperCls = wrapperCls;
134
+ }
135
+ }
136
+ }
137
+
138
+ Neo.applyClassConfig(Form);
139
+
140
+ export default Form;
package/src/list/Base.mjs CHANGED
@@ -37,6 +37,12 @@ class Base extends Component {
37
37
  * @member {String[]} baseCls=['neo-list']
38
38
  */
39
39
  baseCls: ['neo-list'],
40
+ /**
41
+ * An optional record field to make items non-clickable and visually greyed out.
42
+ * The field expects the Boolean type.
43
+ * @member {String} disabledField='disabled'
44
+ */
45
+ disabledField: 'disabled',
40
46
  /**
41
47
  * @member {Boolean} disableSelection_=false
42
48
  */
@@ -373,10 +379,14 @@ class Base extends Component {
373
379
 
374
380
  if (!me.disableSelection && selectionModel) {
375
381
  if (selectionModel.isSelected(itemId)) {
376
- cls.push(selectionModel.selectedCls);
382
+ cls.push(selectionModel.selectedCls)
377
383
  }
378
384
  }
379
385
 
386
+ if (record[me.disabledField]) {
387
+ cls.push('neo-disabled')
388
+ }
389
+
380
390
  item = {
381
391
  tag : isHeader ? 'dt' : me.itemTagName,
382
392
  cls,
@@ -83,9 +83,11 @@ class ListModel extends Model {
83
83
  if (item) {
84
84
  recordId = view.getItemRecordId(item);
85
85
  index = store.indexOf(recordId) + step;
86
+ record = store.getAt(index);
86
87
 
87
- while (store.getAt(index)?.isHeader === true) {
88
+ while (record?.[view.disabledField] === true || record?.isHeader === true) {
88
89
  index += step;
90
+ record = store.getAt(index)
89
91
  }
90
92
 
91
93
  if (index < 0) {
@@ -77,6 +77,10 @@ class Container extends BaseContainer {
77
77
  * @member {Boolean} showHeaderFilters_=false
78
78
  */
79
79
  showHeaderFilters_: false,
80
+ /**
81
+ * @member {Boolean} sortable_=true
82
+ */
83
+ sortable_: true,
80
84
  /**
81
85
  * @member {Neo.data.Store} store_=null
82
86
  */
@@ -125,6 +129,7 @@ class Container extends BaseContainer {
125
129
  module : header.Toolbar,
126
130
  id : me.headerToolbarId,
127
131
  showHeaderFilters: me.showHeaderFilters,
132
+ sortable : me.sortable,
128
133
  ...me.headerToolbarConfig
129
134
  }, {
130
135
  module : View,
@@ -162,6 +167,18 @@ class Container extends BaseContainer {
162
167
  }
163
168
  }
164
169
 
170
+ /**
171
+ * Triggered after the sortable config got changed
172
+ * @param {Boolean} value
173
+ * @param {Boolean} oldValue
174
+ * @protected
175
+ */
176
+ afterSetSortable(value, oldValue) {
177
+ if (oldValue !== undefined) {
178
+ Neo.getComponent(this.headerToolbarId).sortable = value;
179
+ }
180
+ }
181
+
165
182
  /**
166
183
  * Triggered after the useCustomScrollbars config got changed
167
184
  * @param {Boolean} value
@@ -85,6 +85,10 @@ class Button extends BaseButton {
85
85
  * @member {Boolean} showHeaderFilter_=false
86
86
  */
87
87
  showHeaderFilter_: false,
88
+ /**
89
+ * @member {Boolean} sortable_=true
90
+ */
91
+ sortable_: true,
88
92
  /**
89
93
  * @member {Object} _vdom
90
94
  */
@@ -107,24 +111,19 @@ class Button extends BaseButton {
107
111
  construct(config) {
108
112
  super.construct(config);
109
113
 
110
- let me = this,
111
- listeners = {
112
- click: me.onButtonClick,
113
- scope: me
114
- };
115
-
114
+ let me = this;
115
+
116
116
  if (me.draggable) {
117
- Object.assign(listeners, {
117
+ me.addDomListeners({
118
118
  dragend : me.onDragEnd,
119
119
  dragenter: me.onDragEnter,
120
120
  dragleave: me.onDragLeave,
121
121
  dragover : me.onDragOver,
122
122
  dragstart: me.onDragStart,
123
123
  drop : me.onDrop,
124
+ scope : me
124
125
  });
125
126
  }
126
-
127
- me.addDomListeners(listeners);
128
127
  }
129
128
 
130
129
  /**
@@ -227,6 +226,34 @@ class Button extends BaseButton {
227
226
  me.update();
228
227
  }
229
228
 
229
+ /**
230
+ * Triggered after the sortable config got changed
231
+ * @param {Boolean} value
232
+ * @param {Boolean} oldValue
233
+ * @protected
234
+ */
235
+ afterSetSortable(value, oldValue) {
236
+ let me = this,
237
+ cls = me.cls;
238
+
239
+ if (value === true) {
240
+ NeoArray.remove(cls, 'neo-sort-hidden');
241
+ me.addDomListeners({
242
+ click: me.onButtonClick,
243
+ scope: me
244
+ });
245
+ } else {
246
+ NeoArray.add(cls, 'neo-sort-hidden');
247
+ me.removeDomListeners({
248
+ click: me.onButtonClick,
249
+ scope: me
250
+ });
251
+ }
252
+
253
+ me.cls = cls;
254
+ me.update();
255
+ }
256
+
230
257
  /**
231
258
  * Triggered before the align config gets changed
232
259
  * @param {String} value
@@ -34,6 +34,10 @@ class Toolbar extends BaseToolbar {
34
34
  * @member {Boolean} showHeaderFilters_=false
35
35
  */
36
36
  showHeaderFilters_: false,
37
+ /**
38
+ * @member {Boolean} sortable=true
39
+ */
40
+ sortable: true,
37
41
  /**
38
42
  * @member {Object} _vdom={tag:'thead',cn:[{tag:'tr',cn:[]}]}
39
43
  */
@@ -63,6 +67,26 @@ class Toolbar extends BaseToolbar {
63
67
  }
64
68
  }
65
69
 
70
+ /**
71
+ * Triggered after the sortable config got changed
72
+ * @param {Boolean} value
73
+ * @param {Boolean} oldValue
74
+ * @protected
75
+ */
76
+ afterSetSortable(value, oldValue) {
77
+ if (oldValue !== undefined) {
78
+ let me = this;
79
+
80
+ me.items.forEach(item => {
81
+ item.setSilent({
82
+ sortable: value
83
+ });
84
+ });
85
+
86
+ me.update();
87
+ }
88
+ }
89
+
66
90
  /**
67
91
  *
68
92
  */
@@ -98,7 +122,8 @@ class Toolbar extends BaseToolbar {
98
122
  } else {
99
123
  item.vdom.cls = []; // remove the button cls from the th tag
100
124
  }
101
-
125
+
126
+ item.sortable = me.sortable;
102
127
  item.wrapperStyle = style;
103
128
 
104
129
  // inverse loop direction