neo.mjs 5.10.3 → 5.10.5
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/buildScripts/createClass.mjs +10 -2
- package/examples/ConfigurationViewport.mjs +6 -2
- package/examples/ServiceWorker.mjs +2 -2
- package/examples/component/process/MainContainer.mjs +90 -0
- package/examples/component/process/app.mjs +6 -0
- package/examples/component/process/index.html +11 -0
- package/examples/component/process/neo-config.json +6 -0
- package/examples/component/process/realWorldExample/MainContainer.mjs +334 -0
- package/examples/component/process/realWorldExample/RangeHeader.jpg +0 -0
- package/examples/component/process/realWorldExample/app.mjs +6 -0
- package/examples/component/process/realWorldExample/index.html +11 -0
- package/examples/component/process/realWorldExample/neo-config.json +6 -0
- package/examples/component/progress/MainContainer.mjs +71 -0
- package/examples/component/progress/app.mjs +6 -0
- package/examples/component/progress/index.html +11 -0
- package/examples/component/progress/neo-config.json +6 -0
- package/examples/component/toast/MainContainer.mjs +9 -6
- package/examples/component/toast/MainContainerController.mjs +5 -5
- package/examples/component/toast/neo-config.json +1 -1
- package/examples/container/accordion/MainContainer.mjs +123 -0
- package/examples/container/accordion/app.mjs +6 -0
- package/examples/container/accordion/index.html +11 -0
- package/examples/container/accordion/neo-config.json +6 -0
- package/package.json +3 -3
- package/resources/scss/src/component/Process.scss +2 -4
- package/resources/scss/src/component/Progress.scss +3 -0
- package/resources/scss/src/container/Accordion.scss +25 -0
- package/resources/scss/src/container/AccordionItem.scss +83 -0
- package/resources/scss/src/container/Dialog.scss +11 -1
- package/resources/scss/src/form/field/CheckBox.scss +1 -0
- package/resources/scss/src/form/field/Range.scss +1 -0
- package/resources/scss/theme-dark/component/Process.scss +8 -8
- package/resources/scss/theme-dark/component/Progress.scss +9 -0
- package/resources/scss/theme-dark/container/Accordion.scss +13 -0
- package/resources/scss/theme-dark/container/AccordionItem.scss +23 -0
- package/resources/scss/theme-light/component/Process.scss +7 -7
- package/resources/scss/theme-light/component/Progress.scss +9 -0
- package/resources/scss/theme-light/container/Accordion.scss +13 -0
- package/resources/scss/theme-light/container/AccordionItem.scss +23 -0
- package/src/DefaultConfig.mjs +2 -2
- package/src/component/Process.mjs +11 -7
- package/src/component/Progress.mjs +113 -0
- package/src/component/Splitter.mjs +5 -4
- package/src/component/Toast.mjs +2 -1
- package/src/container/Accordion.mjs +130 -0
- package/src/container/AccordionItem.mjs +178 -0
- package/src/container/Dialog.mjs +37 -54
- package/src/form/Container.mjs +42 -25
- package/src/form/field/Number.mjs +49 -37
- package/src/form/field/Range.mjs +31 -4
- package/src/form/field/TextArea.mjs +3 -2
- package/src/main/DomEvents.mjs +2 -1
- package/src/manager/Toast.mjs +5 -1
- package/src/util/String.mjs +56 -0
package/src/form/Container.mjs
CHANGED
@@ -198,46 +198,63 @@ class Container extends BaseContainer {
|
|
198
198
|
}
|
199
199
|
|
200
200
|
/**
|
201
|
-
* Set field
|
202
|
-
* @param {Object}
|
201
|
+
* Set field configs by field name or field id
|
202
|
+
* @param {Object} configs={}
|
203
203
|
* @param {Boolean} suspendEvents=false
|
204
204
|
*/
|
205
|
-
async
|
205
|
+
async setConfigs(configs={}, suspendEvents=false) {
|
206
206
|
let me = this,
|
207
207
|
fields = await me.getFields(),
|
208
|
-
isCheckBox, isRadio, path, value;
|
208
|
+
fieldConfigs, isCheckBox, isRadio, path, value;
|
209
209
|
|
210
210
|
fields.forEach(item => {
|
211
|
-
|
212
|
-
|
213
|
-
|
211
|
+
path = me.getFieldPath(item);
|
212
|
+
fieldConfigs = Neo.nsWithArrays(path, false, configs);
|
213
|
+
|
214
|
+
if (fieldConfigs) {
|
215
|
+
if (suspendEvents) {
|
216
|
+
item.suspendEvents = true;
|
217
|
+
}
|
218
|
+
|
219
|
+
isCheckBox = Neo.form.field?.CheckBox && item instanceof Neo.form.field.CheckBox;
|
220
|
+
value = fieldConfigs.value;
|
214
221
|
|
215
|
-
|
216
|
-
|
217
|
-
|
222
|
+
if (isCheckBox) {
|
223
|
+
if (Neo.typeOf(value) === 'Array') {
|
224
|
+
if (value.includes(item.value)) {
|
225
|
+
fieldConfigs.checked = true
|
226
|
+
}
|
227
|
+
} else {
|
228
|
+
fieldConfigs.checked = item.value === value
|
229
|
+
}
|
230
|
+
} else if (value !== undefined) {
|
231
|
+
isRadio = Neo.form.field?.Radio && item instanceof Neo.form.field.Radio;
|
218
232
|
|
219
|
-
|
220
|
-
|
221
|
-
if (value.includes(item.value)) {
|
222
|
-
item.checked = true
|
233
|
+
if (isRadio) {
|
234
|
+
fieldConfigs.checked = item.value === value
|
223
235
|
}
|
224
|
-
} else {
|
225
|
-
item.checked = item.value === value
|
226
236
|
}
|
227
|
-
} else if (value !== undefined) {
|
228
|
-
isRadio = Neo.form.field?.Radio && item instanceof Neo.form.field.Radio;
|
229
237
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
item.
|
238
|
+
item.set(fieldConfigs)
|
239
|
+
|
240
|
+
if (suspendEvents) {
|
241
|
+
delete item.suspendEvents;
|
234
242
|
}
|
235
243
|
}
|
244
|
+
})
|
245
|
+
}
|
236
246
|
|
237
|
-
|
238
|
-
|
239
|
-
|
247
|
+
/**
|
248
|
+
* Set field values by field name or field id
|
249
|
+
* @param {Object} values={}
|
250
|
+
* @param {Boolean} suspendEvents=false
|
251
|
+
*/
|
252
|
+
async setValues(values={}, suspendEvents=false) {
|
253
|
+
Object.entries(values).forEach(([key, value]) => {
|
254
|
+
values[key] = {value}
|
240
255
|
})
|
256
|
+
|
257
|
+
await this.setConfigs(values, suspendEvents)
|
241
258
|
}
|
242
259
|
|
243
260
|
/**
|
@@ -148,7 +148,7 @@ class Number extends Text {
|
|
148
148
|
|
149
149
|
me.changeInputElKey('step', value);
|
150
150
|
|
151
|
-
stepSizeString = String(
|
151
|
+
stepSizeString = String(value);
|
152
152
|
|
153
153
|
me.stepSizeDigits = stepSizeString.includes('.') ? stepSizeString.split('.')[1].length : 0;
|
154
154
|
|
@@ -157,16 +157,44 @@ class Number extends Text {
|
|
157
157
|
|
158
158
|
if (modulo !== 0) { // find the closest valid value
|
159
159
|
if (modulo / value > 0.5) {
|
160
|
-
if
|
161
|
-
|
160
|
+
if (val + value - modulo < me.maxValue) {
|
161
|
+
me.value = val + value - modulo;
|
162
|
+
} else if (val - modulo > me.minValue) {
|
163
|
+
me.value = val - modulo;
|
164
|
+
}
|
162
165
|
} else {
|
163
|
-
if
|
164
|
-
|
166
|
+
if (val - modulo > me.minValue) {
|
167
|
+
me.value = val - modulo;
|
168
|
+
} else if (val + value - modulo < me.maxValue) {
|
169
|
+
me.value = val + value - modulo;
|
170
|
+
}
|
165
171
|
}
|
166
172
|
}
|
167
173
|
}
|
168
174
|
}
|
169
175
|
|
176
|
+
/**
|
177
|
+
* Triggered after the triggerPosition config got changed
|
178
|
+
* @param {String} value
|
179
|
+
* @param {String} oldValue
|
180
|
+
* @protected
|
181
|
+
*/
|
182
|
+
afterSetTriggerPosition(value, oldValue) {
|
183
|
+
oldValue && this.updateTriggers();
|
184
|
+
}
|
185
|
+
|
186
|
+
/**
|
187
|
+
* Triggered after the useSpinButtons config got changed
|
188
|
+
* @param {Boolean} value
|
189
|
+
* @param {Boolean} oldValue
|
190
|
+
* @protected
|
191
|
+
*/
|
192
|
+
afterSetUseSpinButtons(value, oldValue) {
|
193
|
+
if (typeof oldValue === 'boolean') {
|
194
|
+
this.updateTriggers();
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
170
198
|
/**
|
171
199
|
* Triggered before the maxLength config gets changed
|
172
200
|
* @param {Number|null} value
|
@@ -195,28 +223,6 @@ class Number extends Text {
|
|
195
223
|
return null;
|
196
224
|
}
|
197
225
|
|
198
|
-
/**
|
199
|
-
* Triggered after the triggerPosition config got changed
|
200
|
-
* @param {String} value
|
201
|
-
* @param {String} oldValue
|
202
|
-
* @protected
|
203
|
-
*/
|
204
|
-
afterSetTriggerPosition(value, oldValue) {
|
205
|
-
oldValue && this.updateTriggers();
|
206
|
-
}
|
207
|
-
|
208
|
-
/**
|
209
|
-
* Triggered after the useSpinButtons config got changed
|
210
|
-
* @param {Boolean} value
|
211
|
-
* @param {Boolean} oldValue
|
212
|
-
* @protected
|
213
|
-
*/
|
214
|
-
afterSetUseSpinButtons(value, oldValue) {
|
215
|
-
if (typeof oldValue === 'boolean') {
|
216
|
-
this.updateTriggers();
|
217
|
-
}
|
218
|
-
}
|
219
|
-
|
220
226
|
/**
|
221
227
|
* Triggered before the triggerPosition config gets changed
|
222
228
|
* @param {String} value
|
@@ -229,18 +235,24 @@ class Number extends Text {
|
|
229
235
|
|
230
236
|
/**
|
231
237
|
* Triggered before the value config gets changed
|
232
|
-
* @param {Number} value
|
238
|
+
* @param {Number|String} value
|
233
239
|
* @param {Number} oldValue
|
234
240
|
* @protected
|
235
241
|
*/
|
236
242
|
beforeSetValue(value, oldValue) {
|
237
|
-
if (
|
238
|
-
return
|
239
|
-
}
|
240
|
-
|
243
|
+
if (value === null || value === '') {
|
244
|
+
return null;
|
245
|
+
}
|
246
|
+
|
247
|
+
if (!Neo.isNumber(value)) {
|
248
|
+
value = +value;
|
249
|
+
}
|
250
|
+
|
251
|
+
if (this.stepSizeDigits > 0) {
|
252
|
+
value = +value.toFixed(this.stepSizeDigits);
|
241
253
|
}
|
242
254
|
|
243
|
-
return value
|
255
|
+
return value;
|
244
256
|
}
|
245
257
|
|
246
258
|
/**
|
@@ -366,7 +378,7 @@ class Number extends Text {
|
|
366
378
|
}
|
367
379
|
|
368
380
|
me.removeTrigger('spindown', true, triggers);
|
369
|
-
me.removeTrigger('spinup',
|
381
|
+
me.removeTrigger('spinup', true, triggers);
|
370
382
|
} else {
|
371
383
|
if (!me.hasTrigger('spindown')) {
|
372
384
|
triggers.push(SpinDownTrigger);
|
@@ -379,8 +391,8 @@ class Number extends Text {
|
|
379
391
|
me.removeTrigger('spinupdown', true, triggers);
|
380
392
|
}
|
381
393
|
} else {
|
382
|
-
me.removeTrigger('spindown',
|
383
|
-
me.removeTrigger('spinup',
|
394
|
+
me.removeTrigger('spindown', true, triggers);
|
395
|
+
me.removeTrigger('spinup', true, triggers);
|
384
396
|
me.removeTrigger('spinupdown', true, triggers);
|
385
397
|
}
|
386
398
|
|
@@ -392,7 +404,7 @@ class Number extends Text {
|
|
392
404
|
* @param {Boolean} silent=true
|
393
405
|
* @returns {Boolean} Returns true in case there are no client-side errors
|
394
406
|
*/
|
395
|
-
validate(silent=true) {
|
407
|
+
validate(silent = true) {
|
396
408
|
let me = this,
|
397
409
|
value = me.value,
|
398
410
|
isNumber = Neo.isNumber(value),
|
package/src/form/field/Range.mjs
CHANGED
@@ -30,6 +30,11 @@ class Range extends Number {
|
|
30
30
|
* @member {String} inputType='range'
|
31
31
|
*/
|
32
32
|
inputType: 'range',
|
33
|
+
/**
|
34
|
+
* If true, shows the result of the slider in the label
|
35
|
+
* @member {Boolean} showResultInLabel=false
|
36
|
+
*/
|
37
|
+
showResultInLabel: false,
|
33
38
|
/**
|
34
39
|
* @member {Array} tickmarks_=[]
|
35
40
|
*/
|
@@ -37,7 +42,7 @@ class Range extends Number {
|
|
37
42
|
/**
|
38
43
|
* @member {Boolean} useInputEvent=false
|
39
44
|
*/
|
40
|
-
useInputEvent
|
45
|
+
useInputEvent: false,
|
41
46
|
/**
|
42
47
|
* Disables the field.Number buttons
|
43
48
|
* @member {Boolean} useInputEvent=false
|
@@ -57,14 +62,16 @@ class Range extends Number {
|
|
57
62
|
if (me.useInputEvent) {
|
58
63
|
me.addDomListeners({
|
59
64
|
input: {
|
60
|
-
fn
|
61
|
-
id
|
62
|
-
scope
|
65
|
+
fn : me.onInputValueChange,
|
66
|
+
id : me.vdom.cn[2].id,
|
67
|
+
scope: me
|
63
68
|
}
|
64
69
|
});
|
65
70
|
}
|
66
71
|
|
67
72
|
inputEl.cls = ['neo-rangefield-input']; // replace neo-textfield-input
|
73
|
+
|
74
|
+
me.addValueToLabel();
|
68
75
|
}
|
69
76
|
|
70
77
|
/**
|
@@ -76,6 +83,26 @@ class Range extends Number {
|
|
76
83
|
afterSetTickmarks(value, oldValue) {
|
77
84
|
// todo
|
78
85
|
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Override the NumberField implementation
|
89
|
+
* @param {Object} data
|
90
|
+
*/
|
91
|
+
afterSetValue(value, oldValue) {
|
92
|
+
this.addValueToLabel();
|
93
|
+
super.afterSetValue(value, oldValue);
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Update label with value
|
98
|
+
*/
|
99
|
+
addValueToLabel() {
|
100
|
+
const me = this;
|
101
|
+
|
102
|
+
if (me.showResultInLabel) {
|
103
|
+
me.getLabelEl().innerHTML = `[${me.value}] ` + me.labelText;
|
104
|
+
}
|
105
|
+
}
|
79
106
|
}
|
80
107
|
|
81
108
|
Neo.applyClassConfig(Range);
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import
|
1
|
+
import StringUtil from '../../util/String.mjs';
|
2
|
+
import Text from './Text.mjs';
|
2
3
|
|
3
4
|
/**
|
4
5
|
*
|
@@ -121,7 +122,7 @@ class TextArea extends Text {
|
|
121
122
|
let inputEl = this.getInputEl();
|
122
123
|
|
123
124
|
if (inputEl) {
|
124
|
-
inputEl.html = value;
|
125
|
+
inputEl.html = StringUtil.escapeHtml(value);
|
125
126
|
}
|
126
127
|
|
127
128
|
super.afterSetValue(value, oldValue);
|
package/src/main/DomEvents.mjs
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import Base from '../core/Base.mjs';
|
2
2
|
import Observable from '../core/Observable.mjs';
|
3
|
+
import StringUtil from '../util/String.mjs';
|
3
4
|
import TouchDomEvents from './mixin/TouchDomEvents.mjs';
|
4
5
|
|
5
6
|
const globalDomEvents = [
|
@@ -415,7 +416,7 @@ class DomEvents extends Base {
|
|
415
416
|
data = {
|
416
417
|
...this.getEventData(event),
|
417
418
|
valid: target.checkValidity(),
|
418
|
-
value: target.value
|
419
|
+
value: (target.tagName === 'INPUT') ? StringUtil.escapeHtml(target.value) : target.value
|
419
420
|
};
|
420
421
|
|
421
422
|
// input and change events can pass a FileList for input type file
|
package/src/manager/Toast.mjs
CHANGED
@@ -204,7 +204,11 @@ class Toast extends Base {
|
|
204
204
|
component.style = moveObj;
|
205
205
|
component.update();
|
206
206
|
|
207
|
-
|
207
|
+
// Sometimes the index is already reduced
|
208
|
+
// so the last index might not be available
|
209
|
+
if(rects[index]) {
|
210
|
+
acc = acc + rects[index].height;
|
211
|
+
}
|
208
212
|
}
|
209
213
|
}
|
210
214
|
}
|
@@ -0,0 +1,56 @@
|
|
1
|
+
import Base from '../core/Base.mjs';
|
2
|
+
|
3
|
+
/**
|
4
|
+
* @class Neo.util.StringUtil
|
5
|
+
* @extends Neo.core.Base
|
6
|
+
*/
|
7
|
+
class StringUtil extends Base {
|
8
|
+
static config = {
|
9
|
+
/**
|
10
|
+
* @member {String} className='Neo.util.StringUtil'
|
11
|
+
* @protected
|
12
|
+
*/
|
13
|
+
className: 'Neo.util.StringUtil'
|
14
|
+
}
|
15
|
+
|
16
|
+
static escapedChars = {
|
17
|
+
'&': '&',
|
18
|
+
'<': '<',
|
19
|
+
'>': '>',
|
20
|
+
'"': '"',
|
21
|
+
'\'': '''
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* Escape HTML special characters
|
26
|
+
* @param {String} value
|
27
|
+
*/
|
28
|
+
static escapeHtml(value) {
|
29
|
+
if (Neo.typeOf(value) !== 'String') {
|
30
|
+
return value;
|
31
|
+
}
|
32
|
+
|
33
|
+
return value.replace(/[&<>"']/g, (char) => this.escapedChars[char] || char);
|
34
|
+
}
|
35
|
+
|
36
|
+
/**
|
37
|
+
* Unescape HTML special characters
|
38
|
+
* @param {String} value
|
39
|
+
*/
|
40
|
+
static unescapeHtml(value) {
|
41
|
+
if (Neo.typeOf(value) !== 'String') {
|
42
|
+
return value;
|
43
|
+
}
|
44
|
+
|
45
|
+
return value.replace(/(&)|(<)|(>)|(")|(')/g, (entity) => this.getKeyByValue(entity) || entity);
|
46
|
+
}
|
47
|
+
|
48
|
+
static getKeyByValue(value) {
|
49
|
+
return Object.keys(this.escapedChars).find(key => this.escapedChars[key] === value);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
|
54
|
+
Neo.applyClassConfig(StringUtil);
|
55
|
+
|
56
|
+
export default StringUtil;
|