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.
- package/.github/CODEBASE_OVERVIEW.md +0 -1
- package/.github/CODE_OF_CONDUCT.md +0 -1
- package/.github/CONCEPT.md +0 -1
- package/.github/GETTING_STARTED.md +0 -1
- package/.github/NEOMJS_HISTORY.md +0 -1
- package/.github/STORY.md +0 -1
- package/.github/VISION.md +2 -126
- package/BACKERS.md +0 -1
- package/CONTRIBUTING.md +0 -1
- package/LICENSE +1 -1
- package/README.md +5 -1
- package/apps/ServiceWorker.mjs +2 -2
- package/apps/portal/index.html +1 -1
- package/apps/portal/view/about/Container.mjs +1 -1
- package/apps/portal/view/home/FooterContainer.mjs +1 -1
- package/apps/portal/view/services/Component.mjs +0 -9
- package/examples/ConfigurationViewport.mjs +21 -8
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/component/magicmovetext/MainContainer.mjs +90 -0
- package/examples/component/magicmovetext/app.mjs +6 -0
- package/examples/component/magicmovetext/index.html +11 -0
- package/examples/component/magicmovetext/neo-config.json +6 -0
- package/examples/grid/bigData/ControlsContainer.mjs +142 -84
- package/package.json +9 -7
- package/resources/scss/src/component/MagicMoveText.scss +45 -0
- package/resources/scss/src/examples/ConfigurationViewport.scss +27 -0
- package/resources/scss/src/examples/grid/bigData/ControlsContainer.scss +10 -1
- package/src/DefaultConfig.mjs +2 -2
- package/src/component/MagicMoveText.mjs +306 -0
- package/src/data/Store.mjs +12 -0
- package/src/grid/Container.mjs +1 -1
- package/src/grid/View.mjs +183 -67
- package/src/grid/header/Toolbar.mjs +1 -1
- package/src/main/DomAccess.mjs +18 -24
- package/src/selection/grid/CellModel.mjs +7 -3
- package/src/selection/grid/RowModel.mjs +2 -0
- package/src/selection/grid/_export.mjs +8 -0
- package/src/util/ClassSystem.mjs +4 -4
- 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 = ' '
|
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);
|
package/src/data/Store.mjs
CHANGED
@@ -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
|
package/src/grid/Container.mjs
CHANGED
@@ -522,7 +522,7 @@ class GridContainer extends BaseContainer {
|
|
522
522
|
if (!me.initialResizeEvent) {
|
523
523
|
await me.passSizeToView(true);
|
524
524
|
|
525
|
-
me.view.
|
525
|
+
me.view.updateMountedAndVisibleColumns();
|
526
526
|
|
527
527
|
await me.headerToolbar.passSizeToView()
|
528
528
|
} else {
|