neo.mjs 3.0.2 → 3.0.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/examples/list/animate/List.mjs +1 -1
- package/examples/list/animate/MainContainer.mjs +44 -5
- package/examples/list/animate/MainStore.mjs +17 -0
- package/package.json +4 -4
- package/resources/scss/src/examples/list/animate/List.scss +0 -1
- package/src/collection/Filter.mjs +7 -2
- package/src/list/Base.mjs +1 -1
- package/src/list/plugin/Animate.mjs +218 -71
- package/src/main/addon/Stylesheet.mjs +35 -2
- package/src/plugin/Base.mjs +5 -1
- package/src/util/Css.mjs +19 -5
|
@@ -36,7 +36,7 @@ class List extends BaseList {
|
|
|
36
36
|
|
|
37
37
|
return [
|
|
38
38
|
{cls: ['neo-list-item-content'], id: `${id}__content`, cn: [
|
|
39
|
-
{tag: 'img', id: `${id}__image`, src:
|
|
39
|
+
{tag: 'img', id: `${id}__image`, src: `${Neo.config.resourcesPath}examples/${record.image}`},
|
|
40
40
|
{cls: ['neo-list-item-text'], id: `${id}__content_wrapper`, cn: [
|
|
41
41
|
{html: record.firstname, id: `${id}__firstname`},
|
|
42
42
|
{cls: ['neo-lastname'], id: `${id}__lastname`, html: record.lastname},
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import CheckBox
|
|
2
|
-
import List
|
|
3
|
-
import MainStore
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
import CheckBox from '../../../src/form/field/CheckBox.mjs';
|
|
2
|
+
import List from './List.mjs';
|
|
3
|
+
import MainStore from './MainStore.mjs';
|
|
4
|
+
import NumberField from '../../../src/form/field/Number.mjs';
|
|
5
|
+
import TextField from '../../../src/form/field/Text.mjs';
|
|
6
|
+
import Toolbar from '../../../src/container/Toolbar.mjs';
|
|
7
|
+
import Viewport from '../../../src/container/Viewport.mjs';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* @class Neo.examples.list.animate.MainContainer
|
|
@@ -54,6 +56,27 @@ class MainContainer extends Viewport {
|
|
|
54
56
|
listeners : {change: me.changeIsOnlineFilter.bind(me)},
|
|
55
57
|
style : {marginLeft: '50px'}
|
|
56
58
|
}]
|
|
59
|
+
}, {
|
|
60
|
+
module : TextField,
|
|
61
|
+
flex : 'none',
|
|
62
|
+
labelText : 'Search',
|
|
63
|
+
labelWidth: 60,
|
|
64
|
+
listeners : {change: me.changeNameFilter.bind(me)},
|
|
65
|
+
style : {marginLeft: '10px'},
|
|
66
|
+
width : 262
|
|
67
|
+
}, {
|
|
68
|
+
module : NumberField,
|
|
69
|
+
clearToOriginalValue: true,
|
|
70
|
+
flex : 'none',
|
|
71
|
+
labelText : 'Transition Duration',
|
|
72
|
+
labelWidth : 150,
|
|
73
|
+
listeners : {change: me.changeTransitionDuration.bind(me)},
|
|
74
|
+
maxValue : 5000,
|
|
75
|
+
minValue : 100,
|
|
76
|
+
stepSize : 100,
|
|
77
|
+
style : {marginLeft: '10px'},
|
|
78
|
+
value : 500,
|
|
79
|
+
width : 262
|
|
57
80
|
}, {
|
|
58
81
|
module: List,
|
|
59
82
|
store : MainStore
|
|
@@ -69,6 +92,15 @@ class MainContainer extends Viewport {
|
|
|
69
92
|
store.getFilter('isOnline').disabled = !data.value;
|
|
70
93
|
}
|
|
71
94
|
|
|
95
|
+
/**
|
|
96
|
+
* @param {Object} data
|
|
97
|
+
*/
|
|
98
|
+
changeNameFilter(data) {
|
|
99
|
+
let store = this.down({module: List}).store;
|
|
100
|
+
|
|
101
|
+
store.getFilter('name').value = data.value;
|
|
102
|
+
}
|
|
103
|
+
|
|
72
104
|
/**
|
|
73
105
|
* @param {String} property
|
|
74
106
|
* @param {Object} data
|
|
@@ -97,6 +129,13 @@ class MainContainer extends Viewport {
|
|
|
97
129
|
|
|
98
130
|
me.sortBy = property;
|
|
99
131
|
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @param {Object} data
|
|
135
|
+
*/
|
|
136
|
+
changeTransitionDuration(data) {
|
|
137
|
+
this.down({module: List}).getPlugin('animate').transitionDuration = data.value;
|
|
138
|
+
}
|
|
100
139
|
}
|
|
101
140
|
|
|
102
141
|
Neo.applyClassConfig(MainContainer);
|
|
@@ -17,6 +17,23 @@ class MainStore extends Store {
|
|
|
17
17
|
disabled : true,
|
|
18
18
|
property : 'isOnline',
|
|
19
19
|
value : true
|
|
20
|
+
}, {
|
|
21
|
+
property : 'name',
|
|
22
|
+
value : null,
|
|
23
|
+
|
|
24
|
+
filterBy: opts => {
|
|
25
|
+
let record = opts.item,
|
|
26
|
+
value = opts.value?.toLowerCase();
|
|
27
|
+
|
|
28
|
+
if (value) {
|
|
29
|
+
return !(
|
|
30
|
+
record.firstname.toLowerCase().includes(value) ||
|
|
31
|
+
record.lastname .toLowerCase().includes(value)
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
20
37
|
}],
|
|
21
38
|
|
|
22
39
|
sorters: [{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "neo.mjs",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.6",
|
|
4
4
|
"description": "The webworkers driven UI framework",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -36,11 +36,11 @@
|
|
|
36
36
|
"@fortawesome/fontawesome-free": "^5.15.4",
|
|
37
37
|
"@material/mwc-button": "^0.25.3",
|
|
38
38
|
"@material/mwc-textfield": "^0.25.3",
|
|
39
|
-
"autoprefixer": "^10.4.
|
|
39
|
+
"autoprefixer": "^10.4.2",
|
|
40
40
|
"chalk": "^4.1.2",
|
|
41
41
|
"clean-webpack-plugin": "^4.0.0",
|
|
42
42
|
"commander": "^8.3.0",
|
|
43
|
-
"cssnano": "^5.0.
|
|
43
|
+
"cssnano": "^5.0.15",
|
|
44
44
|
"envinfo": "^7.8.1",
|
|
45
45
|
"fs-extra": "^10.0.0",
|
|
46
46
|
"highlightjs-line-numbers.js": "^2.8.0",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"neo-jsdoc": "^1.0.1",
|
|
49
49
|
"neo-jsdoc-x": "^1.0.4",
|
|
50
50
|
"postcss": "^8.4.5",
|
|
51
|
-
"sass": "^1.
|
|
51
|
+
"sass": "^1.47.0",
|
|
52
52
|
"webpack": "^5.65.0",
|
|
53
53
|
"webpack-cli": "^4.9.1",
|
|
54
54
|
"webpack-dev-server": "4.7.2",
|
|
@@ -40,7 +40,7 @@ class Filter extends Base {
|
|
|
40
40
|
*/
|
|
41
41
|
disabled_: false,
|
|
42
42
|
/**
|
|
43
|
-
* Provide a custom filtering function
|
|
43
|
+
* Provide a custom filtering function which has a higher priority than property, operator & value
|
|
44
44
|
* @member {Function|null} filterBy_=null
|
|
45
45
|
*/
|
|
46
46
|
filterBy_: null,
|
|
@@ -173,7 +173,12 @@ class Filter extends Base {
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
if (me._filterBy) {
|
|
176
|
-
return me.filterBy.call(me.scope || me,
|
|
176
|
+
return me.filterBy.call(me.scope || me, {
|
|
177
|
+
allItems,
|
|
178
|
+
filteredItems,
|
|
179
|
+
item,
|
|
180
|
+
value: me._value
|
|
181
|
+
});
|
|
177
182
|
}
|
|
178
183
|
|
|
179
184
|
if (me.includeEmptyValues && (me._value === null || Neo.isEmpty(me._value))) {
|
package/src/list/Base.mjs
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
import Base
|
|
1
|
+
import Base from '../../plugin/Base.mjs';
|
|
2
|
+
import CssUtil from '../../util/Css.mjs';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @class Neo.list.plugin.Animate
|
|
5
6
|
* @extends Neo.plugin.Base
|
|
6
7
|
*/
|
|
7
8
|
class Animate extends Base {
|
|
9
|
+
static getStaticConfig() {return {
|
|
10
|
+
/**
|
|
11
|
+
* Valid values for transitionEasing
|
|
12
|
+
* @member {String[]} transitionEasings=['ease','ease-in','ease-out','ease-in-out','linear']
|
|
13
|
+
* @protected
|
|
14
|
+
* @static
|
|
15
|
+
*/
|
|
16
|
+
transitionEasings: ['ease', 'ease-in', 'ease-out', 'ease-in-out', 'linear']
|
|
17
|
+
}}
|
|
18
|
+
|
|
8
19
|
static getConfig() {return {
|
|
9
20
|
/**
|
|
10
21
|
* @member {String} className='Neo.list.plugin.Animate'
|
|
@@ -42,9 +53,20 @@ class Animate extends Base {
|
|
|
42
53
|
rows: null,
|
|
43
54
|
/**
|
|
44
55
|
* Time in ms. Please ensure to match the CSS based value, in case you change the default.
|
|
45
|
-
* @member {Number}
|
|
56
|
+
* @member {Number} transitionDuration_=500
|
|
57
|
+
*/
|
|
58
|
+
transitionDuration_: 500,
|
|
59
|
+
/**
|
|
60
|
+
* The easing used for fadeIn, fadeOut and position changes.
|
|
61
|
+
* Valid values: 'ease','ease-in','ease-out','ease-in-out','linear'
|
|
62
|
+
* @member {String} transitionEasing_='ease-in-out'
|
|
63
|
+
*/
|
|
64
|
+
transitionEasing_: 'ease-in-out',
|
|
65
|
+
/**
|
|
66
|
+
* The id of the setTimeout() call which gets triggered after a transition is done.
|
|
67
|
+
* @member {Number|null} transitionTimeoutId=null
|
|
46
68
|
*/
|
|
47
|
-
|
|
69
|
+
transitionTimeoutId: null
|
|
48
70
|
}}
|
|
49
71
|
|
|
50
72
|
/**
|
|
@@ -61,9 +83,11 @@ class Animate extends Base {
|
|
|
61
83
|
owner.onStoreFilter = me.onStoreFilter.bind(me);
|
|
62
84
|
|
|
63
85
|
owner.store.on({
|
|
64
|
-
sort : me.
|
|
86
|
+
sort : me.onStoreSort,
|
|
65
87
|
scope: me
|
|
66
88
|
});
|
|
89
|
+
|
|
90
|
+
this.updateTransitionDetails(false);
|
|
67
91
|
}
|
|
68
92
|
|
|
69
93
|
/**
|
|
@@ -77,6 +101,36 @@ class Animate extends Base {
|
|
|
77
101
|
owner.createItem = me.createItem.bind(owner, me);
|
|
78
102
|
}
|
|
79
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Triggered after the transitionDuration config got changed.
|
|
106
|
+
* @param {Boolean} value
|
|
107
|
+
* @param {Boolean} oldValue
|
|
108
|
+
* @protected
|
|
109
|
+
*/
|
|
110
|
+
afterSetTransitionDuration(value, oldValue) {
|
|
111
|
+
this.isConstructed && this.updateTransitionDetails(Neo.isNumber(oldValue));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Triggered after the transitionEasing config got changed.
|
|
116
|
+
* @param {Number} value
|
|
117
|
+
* @param {Number} oldValue
|
|
118
|
+
* @protected
|
|
119
|
+
*/
|
|
120
|
+
afterSetTransitionEasing(value, oldValue) {
|
|
121
|
+
this.isConstructed && this.updateTransitionDetails(!!oldValue);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Triggered before the transitionEasing config gets changed
|
|
126
|
+
* @param {String} value
|
|
127
|
+
* @param {String} oldValue
|
|
128
|
+
* @protected
|
|
129
|
+
*/
|
|
130
|
+
beforeSetTransitionEasing(value, oldValue) {
|
|
131
|
+
return this.beforeSetEnumValue(value, oldValue, 'transitionEasing');
|
|
132
|
+
}
|
|
133
|
+
|
|
80
134
|
/**
|
|
81
135
|
* @param {Neo.list.plugin.Animate} me
|
|
82
136
|
* @param {Object} record
|
|
@@ -105,7 +159,6 @@ class Animate extends Base {
|
|
|
105
159
|
}
|
|
106
160
|
|
|
107
161
|
/**
|
|
108
|
-
*
|
|
109
162
|
* @param {Object} record
|
|
110
163
|
* @param {Number} index
|
|
111
164
|
* @returns {{x: Number, y: Number}}
|
|
@@ -121,6 +174,23 @@ class Animate extends Base {
|
|
|
121
174
|
return {x, y};
|
|
122
175
|
}
|
|
123
176
|
|
|
177
|
+
/**
|
|
178
|
+
* @param {Object} obj
|
|
179
|
+
* @param {String[]} map
|
|
180
|
+
* @param {Boolean} intercept
|
|
181
|
+
* @returns {Number}
|
|
182
|
+
*/
|
|
183
|
+
getItemIndex(obj, map, intercept) {
|
|
184
|
+
if (!intercept) {
|
|
185
|
+
return obj.index;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
let owner = this.owner,
|
|
189
|
+
key = owner.store.keyProperty;
|
|
190
|
+
|
|
191
|
+
return map.indexOf(owner.getItemId(obj.record[key]));
|
|
192
|
+
}
|
|
193
|
+
|
|
124
194
|
/**
|
|
125
195
|
*
|
|
126
196
|
*/
|
|
@@ -136,47 +206,6 @@ class Animate extends Base {
|
|
|
136
206
|
});
|
|
137
207
|
}
|
|
138
208
|
|
|
139
|
-
/**
|
|
140
|
-
* @param {Object} data
|
|
141
|
-
* @param {Object[]} data.items
|
|
142
|
-
* @param {Object[]} data.previousItems
|
|
143
|
-
* @param {Neo.data.Store} data.scope
|
|
144
|
-
*/
|
|
145
|
-
onSort(data) {
|
|
146
|
-
let me = this,
|
|
147
|
-
hasChange = false,
|
|
148
|
-
keyProperty = data.scope.keyProperty,
|
|
149
|
-
owner = me.owner,
|
|
150
|
-
newVdomCn = [],
|
|
151
|
-
vdom = owner.vdom,
|
|
152
|
-
vdomMap = vdom.cn.map(e => e.id),
|
|
153
|
-
fromIndex, itemId;
|
|
154
|
-
|
|
155
|
-
if (vdomMap.length > 0) {
|
|
156
|
-
data.items.forEach((item, index) => {
|
|
157
|
-
itemId = owner.getItemId(item[keyProperty]);
|
|
158
|
-
fromIndex = vdomMap.indexOf(itemId);
|
|
159
|
-
|
|
160
|
-
newVdomCn.push(vdom.cn[fromIndex]);
|
|
161
|
-
|
|
162
|
-
if (fromIndex !== index) {
|
|
163
|
-
hasChange = true;
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
if (hasChange) {
|
|
168
|
-
owner.vdom.cn = newVdomCn;
|
|
169
|
-
|
|
170
|
-
owner.promiseVdomUpdate().then(() => {
|
|
171
|
-
// we need to ensure to get this call into the next animation frame
|
|
172
|
-
setTimeout(() => {
|
|
173
|
-
owner.createItems();
|
|
174
|
-
}, 50);
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
209
|
/**
|
|
181
210
|
* @param {Object} data
|
|
182
211
|
* @param {Boolean} data.isFiltered
|
|
@@ -185,19 +214,37 @@ class Animate extends Base {
|
|
|
185
214
|
* @param {Neo.data.Store} data.scope
|
|
186
215
|
*/
|
|
187
216
|
onStoreFilter(data) {
|
|
188
|
-
let me
|
|
189
|
-
owner
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
217
|
+
let me = this,
|
|
218
|
+
owner = me.owner,
|
|
219
|
+
key = owner.store.keyProperty,
|
|
220
|
+
hasAddedItems = false,
|
|
221
|
+
addedItems = [],
|
|
222
|
+
movedItems = [],
|
|
223
|
+
removedItems = [],
|
|
224
|
+
transitionTimeoutId = me.transitionTimeoutId,
|
|
225
|
+
intercept = !!transitionTimeoutId,
|
|
226
|
+
vdom = owner.vdom,
|
|
227
|
+
index, item, map, position;
|
|
228
|
+
|
|
229
|
+
if (transitionTimeoutId) {
|
|
230
|
+
clearTimeout(transitionTimeoutId);
|
|
231
|
+
me.transitionTimeoutId = null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
map = intercept ? vdom.cn.map(e => e.id) : [];
|
|
195
235
|
|
|
196
236
|
data.items.forEach((record, index) => {
|
|
237
|
+
item = {index, record};
|
|
238
|
+
|
|
197
239
|
if (!data.oldItems.includes(record)) {
|
|
198
|
-
|
|
240
|
+
// flag items which are still inside the DOM (running remove OP)
|
|
241
|
+
if (intercept && map.includes(owner.getItemId(record[key]))) {
|
|
242
|
+
item.reAdded = true;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
addedItems.push(item);
|
|
199
246
|
} else {
|
|
200
|
-
movedItems.push(
|
|
247
|
+
movedItems.push(item);
|
|
201
248
|
}
|
|
202
249
|
});
|
|
203
250
|
|
|
@@ -208,44 +255,144 @@ class Animate extends Base {
|
|
|
208
255
|
});
|
|
209
256
|
|
|
210
257
|
addedItems.forEach(obj => {
|
|
211
|
-
|
|
258
|
+
if (!obj.reAdded) {
|
|
259
|
+
index = me.getItemIndex(obj, map, intercept);
|
|
260
|
+
|
|
261
|
+
if (index > -1) {
|
|
262
|
+
hasAddedItems = true;
|
|
263
|
+
|
|
264
|
+
vdom.cn.splice(index, 0, me.createItem(me, obj.record, obj.index));
|
|
212
265
|
|
|
213
|
-
|
|
214
|
-
|
|
266
|
+
obj.item = vdom.cn[index];
|
|
267
|
+
obj.item.style.opacity = 0;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
215
270
|
});
|
|
216
271
|
|
|
217
|
-
|
|
272
|
+
if (hasAddedItems) {
|
|
273
|
+
owner.vdom = vdom;
|
|
274
|
+
}
|
|
218
275
|
|
|
219
276
|
// ensure to get into the next animation frame
|
|
220
277
|
setTimeout(() => {
|
|
278
|
+
// get the latest version of the vdom, since this is a delayed callback
|
|
221
279
|
vdom = owner.vdom;
|
|
222
280
|
|
|
223
|
-
addedItems.forEach(obj => {
|
|
224
|
-
vdom.cn[obj.index].style.opacity = 1;
|
|
225
|
-
});
|
|
226
|
-
|
|
227
281
|
// new items are already added into the vdom, while old items are not yet removed
|
|
228
282
|
// => we need a map to ensure getting the correct index
|
|
229
283
|
map = vdom.cn.map(e => e.id);
|
|
230
284
|
|
|
285
|
+
addedItems.forEach(obj => {
|
|
286
|
+
index = me.getItemIndex(obj, map, intercept);
|
|
287
|
+
|
|
288
|
+
if (index > -1) {
|
|
289
|
+
// we can change the opacity for re-added items too => the vdom engine will ignore this
|
|
290
|
+
vdom.cn[index].style.opacity = 1;
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
|
|
231
294
|
movedItems.forEach(obj => {
|
|
232
|
-
index
|
|
233
|
-
|
|
234
|
-
|
|
295
|
+
index = me.getItemIndex(obj, map, true); // honor removed items, even without interceptions
|
|
296
|
+
|
|
297
|
+
if (index > -1) {
|
|
298
|
+
position = me.getItemPosition(obj.record, obj.index);
|
|
299
|
+
|
|
300
|
+
Object.assign(vdom.cn[index].style, {
|
|
301
|
+
opacity : 1,
|
|
302
|
+
transform: `translate(${position.x}px, ${position.y}px)`
|
|
303
|
+
});
|
|
304
|
+
}
|
|
235
305
|
});
|
|
236
306
|
|
|
237
307
|
removedItems.forEach(obj => {
|
|
238
|
-
|
|
239
|
-
|
|
308
|
+
index = me.getItemIndex(obj, map, intercept);
|
|
309
|
+
|
|
310
|
+
if (index > -1) {
|
|
311
|
+
obj.item = vdom.cn[index];
|
|
312
|
+
obj.item.style.opacity = 0;
|
|
313
|
+
}
|
|
240
314
|
});
|
|
241
315
|
|
|
242
316
|
owner.vdom = vdom;
|
|
243
317
|
|
|
244
|
-
|
|
245
|
-
owner.createItems();
|
|
246
|
-
}, me.transitionDuration);
|
|
318
|
+
me.triggerTransitionCallback();
|
|
247
319
|
}, 50);
|
|
248
320
|
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @param {Object} data
|
|
324
|
+
* @param {Object[]} data.items
|
|
325
|
+
* @param {Object[]} data.previousItems
|
|
326
|
+
* @param {Neo.data.Store} data.scope
|
|
327
|
+
*/
|
|
328
|
+
onStoreSort(data) {
|
|
329
|
+
let me = this,
|
|
330
|
+
hasChange = false,
|
|
331
|
+
keyProperty = data.scope.keyProperty,
|
|
332
|
+
owner = me.owner,
|
|
333
|
+
newVdomCn = [],
|
|
334
|
+
vdom = owner.vdom,
|
|
335
|
+
vdomMap = vdom.cn.map(e => e.id),
|
|
336
|
+
fromIndex, itemId;
|
|
337
|
+
|
|
338
|
+
if (vdomMap.length > 0) {
|
|
339
|
+
data.items.forEach((item, index) => {
|
|
340
|
+
itemId = owner.getItemId(item[keyProperty]);
|
|
341
|
+
fromIndex = vdomMap.indexOf(itemId);
|
|
342
|
+
|
|
343
|
+
newVdomCn.push(vdom.cn[fromIndex]);
|
|
344
|
+
|
|
345
|
+
if (fromIndex !== index) {
|
|
346
|
+
hasChange = true;
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
if (hasChange) {
|
|
351
|
+
owner.vdom.cn = newVdomCn;
|
|
352
|
+
|
|
353
|
+
owner.vdom = vdom;
|
|
354
|
+
|
|
355
|
+
// we need to ensure to get this call into the next animation frame
|
|
356
|
+
setTimeout(() => {
|
|
357
|
+
owner.createItems();
|
|
358
|
+
}, 50);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
*
|
|
365
|
+
*/
|
|
366
|
+
triggerTransitionCallback() {
|
|
367
|
+
let me = this;
|
|
368
|
+
|
|
369
|
+
me.transitionTimeoutId = setTimeout(() => {
|
|
370
|
+
me.transitionTimeoutId = null;
|
|
371
|
+
|
|
372
|
+
me.owner.createItems();
|
|
373
|
+
}, me.transitionDuration);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* We do not want to apply the style to each list item itself,
|
|
378
|
+
* so we are using Neo.util.Css
|
|
379
|
+
* @param {Boolean} deleteRule
|
|
380
|
+
* @protected
|
|
381
|
+
*/
|
|
382
|
+
updateTransitionDetails(deleteRule) {
|
|
383
|
+
let me = this,
|
|
384
|
+
duration = me.transitionDuration,
|
|
385
|
+
easing = me.transitionEasing,
|
|
386
|
+
id = me.owner.id;
|
|
387
|
+
|
|
388
|
+
deleteRule && CssUtil.deleteRules(`#${id} .neo-list-item`);
|
|
389
|
+
|
|
390
|
+
CssUtil.insertRules([
|
|
391
|
+
`#${id} .neo-list-item {`,
|
|
392
|
+
`transition: opacity ${duration}ms ${easing}, transform ${duration}ms ${easing}`,
|
|
393
|
+
'}'
|
|
394
|
+
].join(''));
|
|
395
|
+
}
|
|
249
396
|
}
|
|
250
397
|
|
|
251
398
|
Neo.applyClassConfig(Animate);
|
|
@@ -8,6 +8,12 @@ import Base from '../../core/Base.mjs';
|
|
|
8
8
|
* @singleton
|
|
9
9
|
*/
|
|
10
10
|
class Stylesheet extends Base {
|
|
11
|
+
/**
|
|
12
|
+
* @member {String} dynamicStyleSheetId='neo-dynamic-stylesheet'
|
|
13
|
+
* @protected
|
|
14
|
+
*/
|
|
15
|
+
dynamicStyleSheetId = 'neo-dynamic-stylesheet';
|
|
16
|
+
|
|
11
17
|
static getConfig() {return {
|
|
12
18
|
/**
|
|
13
19
|
* @member {String} className='Neo.main.addon.Stylesheet'
|
|
@@ -23,6 +29,7 @@ class Stylesheet extends Base {
|
|
|
23
29
|
app: [
|
|
24
30
|
'addThemeFiles',
|
|
25
31
|
'createStyleSheet',
|
|
32
|
+
'deleteCssRules',
|
|
26
33
|
'insertCssRules',
|
|
27
34
|
'swapStyleSheet'
|
|
28
35
|
]
|
|
@@ -137,6 +144,32 @@ class Stylesheet extends Base {
|
|
|
137
144
|
document.head.appendChild(link);
|
|
138
145
|
}
|
|
139
146
|
|
|
147
|
+
/**
|
|
148
|
+
* @param {Object} data
|
|
149
|
+
* @param {Array} data.rules
|
|
150
|
+
* @protected
|
|
151
|
+
*/
|
|
152
|
+
deleteCssRules(data) {
|
|
153
|
+
let styleEl = document.getElementById(this.dynamicStyleSheetId),
|
|
154
|
+
styleSheet = styleEl.sheet,
|
|
155
|
+
cssRules = styleSheet.cssRules,
|
|
156
|
+
i = 0,
|
|
157
|
+
len = data.rules.length,
|
|
158
|
+
j, rulesLen;
|
|
159
|
+
|
|
160
|
+
for (; i < len; i++) {
|
|
161
|
+
j = 0;
|
|
162
|
+
rulesLen = cssRules.length;
|
|
163
|
+
|
|
164
|
+
for (; j < rulesLen; j++) {
|
|
165
|
+
if (cssRules[j].selectorText === data.rules[i]) {
|
|
166
|
+
styleSheet.deleteRule(j);
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
140
173
|
/**
|
|
141
174
|
* @param {String} token
|
|
142
175
|
* @returns {Boolean}
|
|
@@ -162,7 +195,7 @@ class Stylesheet extends Base {
|
|
|
162
195
|
* @protected
|
|
163
196
|
*/
|
|
164
197
|
insertCssRules(data) {
|
|
165
|
-
let styleEl = document.getElementById(
|
|
198
|
+
let styleEl = document.getElementById(this.dynamicStyleSheetId),
|
|
166
199
|
i = 0,
|
|
167
200
|
len = data.rules.length,
|
|
168
201
|
styleSheet;
|
|
@@ -170,7 +203,7 @@ class Stylesheet extends Base {
|
|
|
170
203
|
if (!styleEl) {
|
|
171
204
|
styleEl = document.createElement('style');
|
|
172
205
|
|
|
173
|
-
styleEl.id =
|
|
206
|
+
styleEl.id = this.dynamicStyleSheetId;
|
|
174
207
|
document.head.appendChild(styleEl);
|
|
175
208
|
}
|
|
176
209
|
|
package/src/plugin/Base.mjs
CHANGED
package/src/util/Css.mjs
CHANGED
|
@@ -14,15 +14,29 @@ class Css extends Base {
|
|
|
14
14
|
}}
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* Pass the selectorText of the rules which you want to remove
|
|
18
|
+
* @param {String[]|String} rules
|
|
19
|
+
*/
|
|
20
|
+
static deleteRules(rules) {
|
|
21
|
+
if (!Array.isArray(rules)) {
|
|
22
|
+
rules = [rules];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
Neo.main.addon.Stylesheet.deleteCssRules({
|
|
26
|
+
rules: rules
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {String[]|String} rules
|
|
18
32
|
*/
|
|
19
33
|
static insertRules(rules) {
|
|
34
|
+
if (!Array.isArray(rules)) {
|
|
35
|
+
rules = [rules];
|
|
36
|
+
}
|
|
37
|
+
|
|
20
38
|
Neo.main.addon.Stylesheet.insertCssRules({
|
|
21
39
|
rules: rules
|
|
22
|
-
}).then(function(data) {
|
|
23
|
-
// console.log('inserted CSS rules', data);
|
|
24
|
-
}).catch(function(err) {
|
|
25
|
-
console.log('App: Got error attempting to insert CSS rules', err, rules);
|
|
26
40
|
});
|
|
27
41
|
}
|
|
28
42
|
}
|