neo.mjs 8.21.2 → 8.23.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 (39) hide show
  1. package/.github/CODEBASE_OVERVIEW.md +0 -1
  2. package/.github/CODE_OF_CONDUCT.md +0 -1
  3. package/.github/CONCEPT.md +0 -1
  4. package/.github/GETTING_STARTED.md +0 -1
  5. package/.github/NEOMJS_HISTORY.md +0 -1
  6. package/.github/STORY.md +0 -1
  7. package/.github/VISION.md +2 -126
  8. package/BACKERS.md +0 -1
  9. package/CONTRIBUTING.md +0 -1
  10. package/LICENSE +1 -1
  11. package/README.md +5 -1
  12. package/apps/ServiceWorker.mjs +2 -2
  13. package/apps/portal/index.html +1 -1
  14. package/apps/portal/view/about/Container.mjs +1 -1
  15. package/apps/portal/view/home/FooterContainer.mjs +1 -1
  16. package/apps/portal/view/services/Component.mjs +0 -9
  17. package/examples/ConfigurationViewport.mjs +21 -8
  18. package/examples/ServiceWorker.mjs +2 -2
  19. package/examples/component/magicmovetext/MainContainer.mjs +90 -0
  20. package/examples/component/magicmovetext/app.mjs +6 -0
  21. package/examples/component/magicmovetext/index.html +11 -0
  22. package/examples/component/magicmovetext/neo-config.json +6 -0
  23. package/examples/grid/bigData/ControlsContainer.mjs +142 -84
  24. package/package.json +9 -7
  25. package/resources/scss/src/component/MagicMoveText.scss +45 -0
  26. package/resources/scss/src/examples/ConfigurationViewport.scss +27 -0
  27. package/resources/scss/src/examples/grid/bigData/ControlsContainer.scss +10 -1
  28. package/src/DefaultConfig.mjs +2 -2
  29. package/src/component/MagicMoveText.mjs +306 -0
  30. package/src/data/Store.mjs +12 -0
  31. package/src/grid/Container.mjs +1 -1
  32. package/src/grid/View.mjs +183 -67
  33. package/src/grid/header/Toolbar.mjs +1 -1
  34. package/src/main/DomAccess.mjs +18 -24
  35. package/src/selection/grid/CellModel.mjs +7 -3
  36. package/src/selection/grid/RowModel.mjs +2 -0
  37. package/src/selection/grid/_export.mjs +8 -0
  38. package/src/util/ClassSystem.mjs +4 -4
  39. package/resources/scss/src/examples/ConfigurationPanel.scss +0 -25
@@ -0,0 +1,306 @@
1
+ import Component from '../component/Base.mjs';
2
+
3
+ /**
4
+ * Deeply inspired by https://github.com/yangshun 's video on LinkedIn
5
+ * as well as Apple's Keynote Magic Move effect
6
+ * @class Neo.component.MagicMoveText
7
+ * @extends Neo.component.Base
8
+ */
9
+ class MagicMoveText extends Component {
10
+ static config = {
11
+ /**
12
+ * @member {String} className='Neo.component.MagicMoveText'
13
+ * @protected
14
+ */
15
+ className: 'Neo.component.MagicMoveText',
16
+ /**
17
+ * @member {String} ntype='magic-move-text'
18
+ * @protected
19
+ */
20
+ ntype: 'magic-move-text',
21
+ /**
22
+ * @member {Boolean} autoCycle_=true
23
+ */
24
+ autoCycle_: true,
25
+ /**
26
+ * @member {Number} autoCycleInterval_=2000
27
+ */
28
+ autoCycleInterval_: 2000,
29
+ /**
30
+ * @member {String[]} baseCls=['neo-magic-move-text']
31
+ * @protected
32
+ */
33
+ baseCls: ['neo-magic-move-text'],
34
+ /**
35
+ * @member {String|null} colorMove=null
36
+ */
37
+ colorMove: null,
38
+ /**
39
+ * @member {String|null} colorFadeIn=null
40
+ */
41
+ colorFadeIn: null,
42
+ /**
43
+ * @member {String|null} colorFadeOut=null
44
+ */
45
+ colorFadeOut: null,
46
+ /**
47
+ * @member {String[]|null} cycleTexts=null
48
+ */
49
+ cycleTexts: null,
50
+ /**
51
+ * @member {String} fontFamily_='Helvetica Neue'
52
+ */
53
+ fontFamily_: 'Helvetica Neue',
54
+ /**
55
+ * @member {String} text_=null
56
+ */
57
+ text_: null,
58
+ /**
59
+ * Time in ms for the fadeIn, fadeOut and move character OPs
60
+ * @member {Number} transitionTime_=500
61
+ */
62
+ transitionTime_: 500,
63
+ /**
64
+ * @member {Object} _vdom
65
+ */
66
+ _vdom:
67
+ {style: {}, cn: [
68
+ {cls: ['neo-content'], cn: []},
69
+ {cls: ['neo-measure-element-wrapper'], removeDom: true, cn: [
70
+ {cls: ['neo-measure-element'], cn:[]}
71
+ ]}
72
+ ]}
73
+ }
74
+
75
+ /**
76
+ * @member {Object[]} chars=[]
77
+ */
78
+ chars = []
79
+ /**
80
+ * @member {Number} currentIndex=0
81
+ */
82
+ currentIndex = 0
83
+ /**
84
+ * @member {Number|null} intervalId=null
85
+ */
86
+ intervalId = null
87
+ /**
88
+ * @member {Object[]} previousChars=[]
89
+ */
90
+ previousChars = []
91
+ /**
92
+ * @member {Object} measureElement
93
+ */
94
+ get measureElement() {
95
+ return this.vdom.cn[1].cn[0]
96
+ }
97
+
98
+ /**
99
+ * Triggered after the autoCycle config got changed
100
+ * @param {Boolean} value
101
+ * @param {Boolean} oldValue
102
+ * @protected
103
+ */
104
+ afterSetAutoCycle(value, oldValue) {
105
+ this.mounted && this.startAutoCycle(value)
106
+ }
107
+
108
+ /**
109
+ * Triggered after the autoCycleInterval config got changed
110
+ * @param {Number} value
111
+ * @param {Number} oldValue
112
+ * @protected
113
+ */
114
+ afterSetAutoCycleInterval(value, oldValue) {
115
+ let me = this;
116
+
117
+ if (oldValue && me.mounted) {
118
+ me.startAutoCycle(false);
119
+ me.startAutoCycle()
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Triggered after the fontFamily config got changed
125
+ * @param {String} value
126
+ * @param {String} oldValue
127
+ * @protected
128
+ */
129
+ afterSetFontFamily(value, oldValue) {
130
+ this.vdom.style.fontFamily = value;
131
+ this.update()
132
+ }
133
+
134
+ /**
135
+ * Triggered after the mounted config got changed
136
+ * @param {Boolean} value
137
+ * @param {Boolean} oldValue
138
+ * @protected
139
+ */
140
+ afterSetMounted(value, oldValue) {
141
+ super.afterSetMounted(value, oldValue);
142
+ this.autoCycle && this.startAutoCycle(value)
143
+ }
144
+
145
+ /**
146
+ * Triggered after the text config got changed
147
+ * @param {String} value
148
+ * @param {String} oldValue
149
+ * @returns {Promise<void>}
150
+ * @protected
151
+ */
152
+ async afterSetText(value, oldValue) {
153
+ let me = this,
154
+ {measureElement} = me;
155
+
156
+ if (oldValue) {
157
+ me.previousChars = me.chars
158
+ }
159
+
160
+ if (value) {
161
+ me.chars = [];
162
+ measureElement.cn = [];
163
+
164
+ value?.split('').forEach(char => {
165
+ me.chars.push({name: char});
166
+
167
+ if (char === ' ') {
168
+ char = '&nbsp;'
169
+ }
170
+
171
+ measureElement.cn.push({tag: 'span', html: char})
172
+ });
173
+
174
+ if (me.mounted) {
175
+ await me.measureChars()
176
+ }
177
+
178
+ await me.updateChars()
179
+ }
180
+ }
181
+
182
+ /**
183
+ * Triggered after the transitionTime config got changed
184
+ * @param {Number} value
185
+ * @param {Number} oldValue
186
+ * @protected
187
+ */
188
+ afterSetTransitionTime(value, oldValue) {
189
+ this.vdom.style['--neo-transition-time'] = value + 'ms';
190
+ this.update()
191
+ }
192
+
193
+ /**
194
+ * @returns {Promise<void>}
195
+ */
196
+ async measureChars() {
197
+ let me = this,
198
+ {measureElement} = me,
199
+ parentRect, rects;
200
+
201
+ delete me.vdom.cn[1].removeDom;
202
+
203
+ await me.promiseUpdate();
204
+ await me.timeout(20);
205
+
206
+ rects = await me.getDomRect([me.vdom.cn[1].id, ...measureElement.cn.map(node => node.id)]);
207
+ parentRect = rects.shift();
208
+
209
+ rects.forEach((rect, index) => {
210
+ me.chars[index].left = `${rect.left - parentRect.left}px`;
211
+ me.chars[index].top = `${rect.top - parentRect.top }px`;
212
+ });
213
+
214
+ me.vdom.cn[1].removeDom = true;
215
+ await me.promiseUpdate()
216
+ }
217
+
218
+ /**
219
+ * @param {Boolean} start=true
220
+ */
221
+ startAutoCycle(start=true) {
222
+ let me = this;
223
+
224
+ if (start) {
225
+ me.intervalId = setInterval(() => {
226
+ me.text = me.cycleTexts[me.currentIndex];
227
+ me.currentIndex = (me.currentIndex + 1) % me.cycleTexts.length
228
+ }, me.autoCycleInterval)
229
+
230
+ me.text && me.measureChars()
231
+ } else {
232
+ clearInterval(me.intervalId)
233
+ }
234
+ }
235
+
236
+ /**
237
+ * @returns {Promise<void>}
238
+ */
239
+ async updateChars() {
240
+ let me = this,
241
+ {chars, previousChars} = me,
242
+ charsContainer = me.vdom.cn[0].cn,
243
+ letters = chars.map(char => char.name),
244
+ char, charNode, index;
245
+
246
+ previousChars.forEach((previousChar, previousIndex) => {
247
+ index = letters.indexOf(previousChar.name);
248
+
249
+ if (index > -1) {
250
+ charNode = charsContainer[previousIndex];
251
+
252
+ charNode.style.color = me.colorMove;
253
+ charNode.style.left = chars[index].left;
254
+ letters[index] = null
255
+ } else {
256
+ charNode = charsContainer[previousIndex];
257
+
258
+ charNode.flag = 'remove'
259
+ }
260
+ });
261
+
262
+ letters.forEach((letter, index) => {
263
+ if (letter !== null) {
264
+ char = chars[index];
265
+
266
+ charsContainer.push({
267
+ html : char.name,
268
+ style: {color: me.colorFadeIn, left: char.left, opacity: 0, top: char.top}
269
+ })
270
+ }
271
+ });
272
+
273
+ await me.promiseUpdate();
274
+
275
+ charsContainer.forEach(charNode => {
276
+ if (charNode.flag === 'remove') {
277
+ charNode.style.color = me.colorFadeOut;
278
+ charNode.style.opacity = 0
279
+ } else {
280
+ charNode.style.opacity = 1
281
+ }
282
+ });
283
+
284
+ await me.promiseUpdate();
285
+ await me.timeout(me.transitionTime);
286
+
287
+ charsContainer.sort((a, b) => parseFloat(a.style.left) - parseFloat(b.style.left));
288
+
289
+ index = charsContainer.length - 1;
290
+
291
+ for (; index >= 0; index--) {
292
+ charNode = charsContainer[index];
293
+
294
+ delete charNode.flag;
295
+ delete charNode.style.color;
296
+
297
+ if (charNode.style.opacity === 0) {
298
+ charsContainer.splice(index, 1)
299
+ }
300
+ }
301
+
302
+ await me.promiseUpdate()
303
+ }
304
+ }
305
+
306
+ export default Neo.setupClass(MagicMoveText);
@@ -330,6 +330,18 @@ class Store extends Base {
330
330
  return this.keyProperty || this.model.keyProperty
331
331
  }
332
332
 
333
+ /**
334
+ * Convenience shortcut to check for int based keyProperties
335
+ * @returns {String|null} lowercase value of the model field type
336
+ */
337
+ getKeyType() {
338
+ let me = this,
339
+ {model} = me,
340
+ keyField = model?.getField(me.getKeyProperty());
341
+
342
+ return keyField?.type?.toLowerCase() || null
343
+ }
344
+
333
345
  /**
334
346
  * @param {Object} opts={}
335
347
  * @param {Object} opts.data
@@ -522,7 +522,7 @@ class GridContainer extends BaseContainer {
522
522
  if (!me.initialResizeEvent) {
523
523
  await me.passSizeToView(true);
524
524
 
525
- me.view.updateVisibleColumns();
525
+ me.view.updateMountedAndVisibleColumns();
526
526
 
527
527
  await me.headerToolbar.passSizeToView()
528
528
  } else {