neo.mjs 4.0.52 → 4.0.55

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.
@@ -83,7 +83,7 @@ if (programOpts.info) {
83
83
  }
84
84
 
85
85
  if (programOpts.className.indexOf('.') !== -1) {
86
- console.error(chalk.red('No .dot-notation avcailable when -d option is selected.'));
86
+ console.error(chalk.red('No .dot-notation available when -d option is selected.'));
87
87
  console.info(chalk.bgCyan('Usage: createClass -d -c <className> -b <baseClass> [-s sourceParent]'));
88
88
  process.exit(1);
89
89
  }
@@ -36,6 +36,12 @@ class MainContainer extends ConfigurationViewport {
36
36
  labelText: 'clearToOriginalValue',
37
37
  listeners: {change: me.onConfigChange.bind(me, 'clearToOriginalValue')},
38
38
  style : {marginTop: '10px'}
39
+ }, {
40
+ module : CheckBox,
41
+ checked : me.exampleComponent.disabled,
42
+ labelText: 'disabled',
43
+ listeners: {change: me.onConfigChange.bind(me, 'disabled')},
44
+ style : {marginTop: '10px'}
39
45
  }, {
40
46
  module : CheckBox,
41
47
  checked : me.exampleComponent.hideLabel,
@@ -145,11 +151,13 @@ class MainContainer extends ConfigurationViewport {
145
151
 
146
152
  createExampleComponent() {
147
153
  return Neo.create(TextField, {
148
- clearable : true,
149
- labelText : 'Label',
150
- labelWidth: 70,
151
- value : 'Hello World',
152
- width : 200
154
+ clearable : true,
155
+ labelPosition: 'inline',
156
+ labelText : 'Label',
157
+ labelWidth : 70,
158
+ minLength : 3,
159
+ value : 'Hello World',
160
+ width : 200
153
161
  });
154
162
  }
155
163
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neo.mjs",
3
- "version": "4.0.52",
3
+ "version": "4.0.55",
4
4
  "description": "The webworkers driven UI framework",
5
5
  "type": "module",
6
6
  "repository": {
@@ -8,7 +8,39 @@
8
8
 
9
9
  &.neo-focus {
10
10
  .neo-input-wrapper {
11
- border-color: v(textfield-border-color-active);
11
+ border-color: v(textfield-border-color-active) !important;
12
+ }
13
+ }
14
+
15
+ &.neo-invalid:not(.neo-disabled) {
16
+ .neo-input-wrapper {
17
+ border-color: v(textfield-border-color-invalid);
18
+ }
19
+
20
+ .neo-label-wrapper {
21
+ .neo-center-border, .neo-left-border, .neo-right-border {
22
+ border-bottom-color: v(textfield-border-color-invalid);
23
+ }
24
+
25
+ .neo-left-border, .neo-right-border {
26
+ border-top-color: v(textfield-border-color-invalid);
27
+ }
28
+
29
+ .neo-left-border {
30
+ border-left-color: v(textfield-border-color-invalid);
31
+ }
32
+
33
+ .neo-right-border {
34
+ border-right-color: v(textfield-border-color-invalid);
35
+ }
36
+ }
37
+ }
38
+
39
+ &.neo-invalid:not(.neo-disabled, .neo-has-content) {
40
+ .neo-label-wrapper {
41
+ .neo-center-border {
42
+ border-top-color: v(textfield-border-color-invalid);
43
+ }
12
44
  }
13
45
  }
14
46
 
@@ -36,7 +68,7 @@
36
68
  }
37
69
 
38
70
  .neo-center-border {
39
- border-top-color: transparent;
71
+ border-top-color: transparent !important;
40
72
  }
41
73
 
42
74
  .neo-left-border {
@@ -70,7 +102,7 @@
70
102
  }
71
103
 
72
104
  .neo-input-wrapper {
73
- border-color: transparent;
105
+ border-color: transparent !important;
74
106
  }
75
107
 
76
108
  .neo-label-wrapper {
@@ -156,10 +188,6 @@
156
188
  margin : 0; // important for Safari => #1125
157
189
  min-height : 25px;
158
190
  width : 30px;
159
-
160
- &:invalid {
161
- border: 1px solid brown;
162
- }
163
191
  }
164
192
  }
165
193
 
@@ -179,14 +207,18 @@
179
207
  outline : none;
180
208
  }
181
209
 
182
- &:invalid {
183
- border-color: brown;
184
- }
185
-
186
210
  &::-webkit-input-placeholder {
187
211
  color : v(textfield-input-placeholder-color) !important;
188
212
  opacity: v(textfield-input-placeholder-opacity) !important;
189
213
  }
214
+
215
+ &.neo-invalid {
216
+ border-color: v(textfield-border-color-invalid);
217
+
218
+ &.neo-disabled {
219
+ border-color: inherit;
220
+ }
221
+ }
190
222
  }
191
223
 
192
224
  .neo-textfield-label {
@@ -1,6 +1,7 @@
1
1
  $neoMap: map-merge($neoMap, (
2
2
  'textfield-border-color' : #424242,
3
3
  'textfield-border-color-active' : #5d83a7,
4
+ 'textfield-border-color-invalid' : brown,
4
5
  'textfield-border-radius' : 0,
5
6
  'textfield-input-background-color' : #2b2b2b,
6
7
  'textfield-input-color' : #ccc,
@@ -13,6 +14,7 @@ $neoMap: map-merge($neoMap, (
13
14
  :root .neo-theme-dark { // .neo-textfield
14
15
  --textfield-border-color : #{neo(textfield-border-color)};
15
16
  --textfield-border-color-active : #{neo(textfield-border-color-active)};
17
+ --textfield-border-color-invalid : #{neo(textfield-border-color-invalid)};
16
18
  --textfield-border-radius : #{neo(textfield-border-radius)};
17
19
  --textfield-input-background-color : #{neo(textfield-input-background-color)};
18
20
  --textfield-input-color : #{neo(textfield-input-color)};
@@ -20,4 +22,4 @@ $neoMap: map-merge($neoMap, (
20
22
  --textfield-input-placeholder-opacity: #{neo(textfield-input-placeholder-opacity)};
21
23
  --textfield-label-color : #{neo(textfield-label-color)};
22
24
  }
23
- }
25
+ }
@@ -1,6 +1,7 @@
1
1
  $neoMap: map-merge($neoMap, (
2
2
  'textfield-border-color' : #ddd,
3
3
  'textfield-border-color-active' : #1c60a0,
4
+ 'textfield-border-color-invalid' : brown,
4
5
  'textfield-border-radius' : 3px,
5
6
  'textfield-input-background-color' : #fff,
6
7
  'textfield-input-color' : #000,
@@ -13,6 +14,7 @@ $neoMap: map-merge($neoMap, (
13
14
  :root .neo-theme-light { // .neo-textfield
14
15
  --textfield-border-color : #{neo(textfield-border-color)};
15
16
  --textfield-border-color-active : #{neo(textfield-border-color-active)};
17
+ --textfield-border-color-invalid : #{neo(textfield-border-color-invalid)};
16
18
  --textfield-border-radius : #{neo(textfield-border-radius)};
17
19
  --textfield-input-background-color : #{neo(textfield-input-background-color)};
18
20
  --textfield-input-color : #{neo(textfield-input-color)};
@@ -20,4 +22,4 @@ $neoMap: map-merge($neoMap, (
20
22
  --textfield-input-placeholder-opacity: #{neo(textfield-input-placeholder-opacity)};
21
23
  --textfield-label-color : #{neo(textfield-label-color)};
22
24
  }
23
- }
25
+ }
@@ -231,6 +231,7 @@ class RecordFactory extends Base {
231
231
  let mapping = field.mapping,
232
232
  maxLength = field.maxLength,
233
233
  minLength = field.minLength,
234
+ nullable = field.nullable,
234
235
  oldValue = recordConfig?.[field.name] || record[field.name],
235
236
  type = field.type?.toLowerCase();
236
237
 
@@ -244,16 +245,23 @@ class RecordFactory extends Base {
244
245
  value = ns[key];
245
246
  }
246
247
 
247
- if (Object.hasOwn(field, maxLength)) {
248
+ if (Object.hasOwn(field, 'maxLength')) {
248
249
  if (value?.toString() > maxLength) {
249
- console.warn(`Setting record field: ${field} value: ${value} conflicts with the maxLength: ${maxLength}`);
250
+ console.warn(`Setting record field: ${field} value: ${value} conflicts with maxLength: ${maxLength}`);
250
251
  return oldValue;
251
252
  }
252
253
  }
253
254
 
254
- if (Object.hasOwn(field, minLength)) {
255
+ if (Object.hasOwn(field, 'minLength')) {
255
256
  if (value?.toString() < minLength) {
256
- console.warn(`Setting record field: ${field} value: ${value} conflicts with the minLength: ${minLength}`);
257
+ console.warn(`Setting record field: ${field} value: ${value} conflicts with minLength: ${minLength}`);
258
+ return oldValue;
259
+ }
260
+ }
261
+
262
+ if (Object.hasOwn(field, 'nullable')) {
263
+ if (nullable === false && value === null) {
264
+ console.warn(`Setting record field: ${field} value: ${value} conflicts with nullable: ${nullable}`);
257
265
  return oldValue;
258
266
  }
259
267
  }
@@ -99,6 +99,7 @@ class Number extends Text {
99
99
  * @protected
100
100
  */
101
101
  afterSetMaxValue(value, oldValue) {
102
+ this.updateValidationIndicators();
102
103
  this.changeInputElKey('max', value);
103
104
  }
104
105
 
@@ -109,6 +110,7 @@ class Number extends Text {
109
110
  * @protected
110
111
  */
111
112
  afterSetMinValue(value, oldValue) {
113
+ this.updateValidationIndicators();
112
114
  this.changeInputElKey('min', value);
113
115
  }
114
116
 
@@ -178,14 +180,17 @@ class Number extends Text {
178
180
  * @returns {Boolean}
179
181
  */
180
182
  isValid() {
181
- let me = this,
182
- value = me.value;
183
+ let me = this,
184
+ maxValue = me.maxValue,
185
+ minValue = me.minValue,
186
+ value = me.value,
187
+ isNumber = Neo.isNumber(value);
183
188
 
184
- if (Neo.isNumber(me.maxValue) && value > me.maxValue) {
189
+ if (Neo.isNumber(maxValue) && isNumber && value > maxValue) {
185
190
  return false;
186
191
  }
187
192
 
188
- if (Neo.isNumber(me.minValue) && value < me.minValue) {
193
+ if (Neo.isNumber(minValue) && isNumber && value < minValue) {
189
194
  return false;
190
195
  }
191
196
 
@@ -10,6 +10,12 @@ import VNodeUtil from '../../util/VNode.mjs';
10
10
  * @extends Neo.form.field.Base
11
11
  */
12
12
  class Text extends Base {
13
+ /**
14
+ * Set this value to false, in case a field should display errors up front
15
+ * @member {Boolean} validBeforeMount=true
16
+ */
17
+ validBeforeMount = true
18
+
13
19
  static getStaticConfig() {return {
14
20
  /**
15
21
  * Valid values for autoCapitalize
@@ -375,6 +381,7 @@ class Text extends Base {
375
381
  * @protected
376
382
  */
377
383
  afterSetMaxLength(value, oldValue) {
384
+ this.updateValidationIndicators();
378
385
  this.changeInputElKey('maxlength', value);
379
386
  }
380
387
 
@@ -385,6 +392,7 @@ class Text extends Base {
385
392
  * @protected
386
393
  */
387
394
  afterSetMinLength(value, oldValue) {
395
+ this.updateValidationIndicators();
388
396
  this.changeInputElKey('minlength', value);
389
397
  }
390
398
 
@@ -437,6 +445,7 @@ class Text extends Base {
437
445
  * @protected
438
446
  */
439
447
  afterSetRequired(value, oldValue) {
448
+ this.updateValidationIndicators();
440
449
  this.changeInputElKey('required', value ? value : null);
441
450
  }
442
451
 
@@ -532,6 +541,7 @@ class Text extends Base {
532
541
  }
533
542
 
534
543
  NeoArray[me.originalConfig.value !== value ? 'add' : 'remove'](me._cls, 'neo-is-dirty');
544
+ me.updateValidationIndicators();
535
545
 
536
546
  me.vdom = vdom;
537
547
 
@@ -873,19 +883,17 @@ class Text extends Base {
873
883
  onFocusLeave(data) {
874
884
  let me = this,
875
885
  centerBorderEl = me.getCenterBorderEl(), // labelPosition: 'inline'
876
- cls = me.cls,
877
- vdom;
886
+ vdom = me.vdom;
887
+
888
+ me.updateValidationIndicators();
878
889
 
879
- NeoArray.remove(cls, 'neo-focus');
890
+ NeoArray.remove(me.cls, 'neo-focus');
880
891
 
881
892
  if (centerBorderEl && me.isEmpty()) {
882
- me._cls = cls; // silent update
883
- vdom = me.vdom;
884
893
  delete centerBorderEl.width;
885
- me.vdom = vdom;
886
- } else {
887
- me.cls = cls;
888
894
  }
895
+
896
+ me.vdom = vdom;
889
897
  }
890
898
 
891
899
  /**
@@ -1011,6 +1019,22 @@ class Text extends Base {
1011
1019
  });
1012
1020
  });
1013
1021
  }
1022
+
1023
+ /**
1024
+ * @param {Boolean} silent=true
1025
+ */
1026
+ updateValidationIndicators(silent=true) {
1027
+ let me = this,
1028
+ vdom = me.vdom;
1029
+
1030
+ if (!(me.validBeforeMount && !me.mounted)) {
1031
+ NeoArray[!me.isValid() ? 'add' : 'remove'](me._cls, 'neo-invalid');
1032
+
1033
+ if (!silent) {
1034
+ me.vdom = vdom;
1035
+ }
1036
+ }
1037
+ }
1014
1038
  }
1015
1039
 
1016
1040
  Neo.applyClassConfig(Text);