cx 24.0.2 → 24.2.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 (62) hide show
  1. package/dist/data.js +15 -26
  2. package/dist/manifest.js +525 -522
  3. package/dist/ui.js +1 -1
  4. package/dist/widgets.js +162 -77
  5. package/locale/de-de.js +6 -1
  6. package/locale/en-us.js +5 -1
  7. package/locale/es-es.js +6 -1
  8. package/locale/fr-fr.js +7 -2
  9. package/locale/nl-nl.js +4 -5
  10. package/locale/pt-pt.js +12 -1
  11. package/locale/sr-latn-ba.js +6 -2
  12. package/package.json +1 -1
  13. package/src/charts/ColorMap.js +4 -6
  14. package/src/charts/axis/Axis.d.ts +96 -96
  15. package/src/charts/axis/Axis.js +252 -252
  16. package/src/data/Expression.js +212 -212
  17. package/src/data/Expression.spec.js +174 -174
  18. package/src/data/StringTemplate.spec.js +105 -105
  19. package/src/data/StructuredSelector.d.ts +1 -1
  20. package/src/data/ops/updateTree.js +1 -1
  21. package/src/data/ops/updateTree.spec.js +16 -14
  22. package/src/ui/Controller.d.ts +182 -182
  23. package/src/ui/Culture.d.ts +0 -3
  24. package/src/ui/DataProxy.d.ts +1 -0
  25. package/src/ui/DataProxy.js +2 -2
  26. package/src/ui/FocusManager.js +171 -171
  27. package/src/ui/Format.js +87 -87
  28. package/src/ui/Instance.d.ts +72 -72
  29. package/src/ui/Localization.js +0 -2
  30. package/src/ui/Rescope.js +2 -2
  31. package/src/ui/Text.js +2 -4
  32. package/src/ui/adapter/DataAdapter.js +7 -12
  33. package/src/ui/adapter/GroupAdapter.d.ts +22 -3
  34. package/src/ui/adapter/TreeAdapter.d.ts +23 -3
  35. package/src/ui/keyboardShortcuts.js +4 -5
  36. package/src/ui/selection/KeySelection.d.ts +1 -1
  37. package/src/ui/selection/PropertySelection.d.ts +1 -1
  38. package/src/ui/selection/PropertySelection.js +2 -4
  39. package/src/ui/selection/Selection.d.ts +1 -1
  40. package/src/widgets/form/ColorField.js +14 -9
  41. package/src/widgets/form/ColorPicker.scss +275 -275
  42. package/src/widgets/form/ColorPicker.variables.scss +22 -22
  43. package/src/widgets/form/DateTimeField.d.ts +86 -86
  44. package/src/widgets/form/DateTimeField.js +573 -572
  45. package/src/widgets/form/Field.js +24 -9
  46. package/src/widgets/form/FieldIcon.js +42 -0
  47. package/src/widgets/form/Label.js +88 -88
  48. package/src/widgets/form/LookupField.d.ts +173 -174
  49. package/src/widgets/form/LookupField.js +1130 -1131
  50. package/src/widgets/form/MonthField.d.ts +37 -38
  51. package/src/widgets/form/MonthField.js +16 -15
  52. package/src/widgets/form/NumberField.d.ts +2 -2
  53. package/src/widgets/form/NumberField.js +13 -13
  54. package/src/widgets/form/Select.d.ts +31 -35
  55. package/src/widgets/form/Select.js +7 -12
  56. package/src/widgets/form/TextArea.js +10 -6
  57. package/src/widgets/form/TextField.d.ts +2 -2
  58. package/src/widgets/form/TextField.js +17 -14
  59. package/src/widgets/form/UploadButton.d.ts +34 -34
  60. package/src/widgets/form/index.js +1 -2
  61. package/src/widgets/grid/Grid.d.ts +5 -2
  62. package/src/widgets/overlay/Dropdown.d.ts +1 -0
@@ -1,88 +1,87 @@
1
- import * as Cx from '../../core';
2
- import { FieldProps } from './Field';
1
+ import * as Cx from "../../core";
2
+ import { FieldProps } from "./Field";
3
3
 
4
4
  interface MonthFieldProps extends FieldProps {
5
-
6
5
  /** Selected month. This should be a Date object or a valid date string consumable by Date.parse function. */
7
- value?: Cx.Prop< string | Date >,
8
-
6
+ value?: Cx.Prop<string | Date>;
7
+
9
8
  /** Set to `true` to allow range select. */
10
- range?: Cx.BooleanProp,
9
+ range?: Cx.BooleanProp;
11
10
 
12
- /**
11
+ /**
13
12
  * Start of the selected month range. This should be a Date object or a valid date string consumable by Date.parse function.
14
13
  * Used only if `range` is set to `true`.
15
14
  */
16
- from?: Cx.Prop< string | Date >,
15
+ from?: Cx.Prop<string | Date>;
17
16
 
18
- /**
17
+ /**
19
18
  * End of the selected month range. This should be a Date object or a valid date string consumable by Date.parse function.
20
- * Used only if `range` is set to `true`.
19
+ * Used only if `range` is set to `true`.
21
20
  */
22
- to?: Cx.Prop< string | Date >,
21
+ to?: Cx.Prop<string | Date>;
23
22
 
24
23
  /** Defaults to `false`. Used to make the field read-only. */
25
- readOnly?: Cx.BooleanProp,
24
+ readOnly?: Cx.BooleanProp;
26
25
 
27
26
  /** The opposite of `disabled`. */
28
- enabled?: Cx.BooleanProp,
27
+ enabled?: Cx.BooleanProp;
29
28
 
30
29
  /** Default text displayed when the field is empty. */
31
- placeholder?: Cx.StringProp,
30
+ placeholder?: Cx.StringProp;
32
31
 
33
32
  /** Minimum date value. This should be a Date object or a valid date string consumable by Date.parse function. */
34
- minValue?: Cx.Prop< string | Date >,
33
+ minValue?: Cx.Prop<string | Date>;
35
34
 
36
35
  /** Set to `true` to disallow the `minValue`. Default value is `false`. */
37
- minExclusive?: Cx.BooleanProp,
36
+ minExclusive?: Cx.BooleanProp;
38
37
 
39
38
  /** Maximum date value. This should be a Date object or a valid date string consumable by Date.parse function. */
40
- maxValue?: Cx.Prop< string | Date >,
41
-
39
+ maxValue?: Cx.Prop<string | Date>;
40
+
42
41
  /** Set to `true` to disallow the `maxValue`. Default value is `false`. */
43
- maxExclusive?: Cx.BooleanProp,
42
+ maxExclusive?: Cx.BooleanProp;
44
43
 
45
44
  /** String representing culture. Default is `en` */
46
- culture?: string,
45
+ culture?: string;
47
46
 
48
- /**
49
- * Set to `true` to hide the clear button. It can be used interchangeably with the `showClear` property.
50
- * Default value is `false`.
47
+ /**
48
+ * Set to `true` to hide the clear button. It can be used interchangeably with the `showClear` property.
49
+ * Default value is `false`.
51
50
  */
52
- hideClear?: boolean,
51
+ hideClear?: boolean;
53
52
 
54
53
  /** Base CSS class to be applied on the field. Defaults to `monthfield`. */
55
- baseClass?: string,
54
+ baseClass?: string;
56
55
 
57
56
  /** Maximum value error text. */
58
- maxValueErrorText?: string,
57
+ maxValueErrorText?: string;
59
58
 
60
59
  /** Maximum exclusive value error text. */
61
- maxExclusiveErrorText?: string,
60
+ maxExclusiveErrorText?: string;
62
61
 
63
62
  /** Minimum value error text. */
64
- minValueErrorText?: string,
63
+ minValueErrorText?: string;
65
64
 
66
65
  /** Minimum exclusive value error text. */
67
- minExclusiveErrorText?: string,
66
+ minExclusiveErrorText?: string;
68
67
 
69
68
  /** Invalid input error text. */
70
- inputErrorText?: string,
69
+ inputErrorText?: string;
71
70
 
72
- /** Name of the icon to be put on the left side of the input. */
73
- icon?: string,
71
+ /** Name or configuration of the icon to be put on the left side of the input. */
72
+ icon?: Cx.StringProp | Cx.Record;
74
73
 
75
- /**
76
- * Set to `false` to hide the clear button. It can be used interchangeably with the `hideClear` property.
77
- * Default value is `true`.
74
+ /**
75
+ * Set to `false` to hide the clear button. It can be used interchangeably with the `hideClear` property.
76
+ * Default value is `true`.
78
77
  */
79
- showClear?: boolean,
78
+ showClear?: boolean;
80
79
 
81
80
  /**
82
81
  * Set to `true` to display the clear button even if `required` is set. Default is `false`.
83
82
  */
84
- alwaysShowClear?: boolean,
85
-
83
+ alwaysShowClear?: boolean;
84
+
86
85
  /** The function that will be used to convert Date objects before writing data to the store.
87
86
  * Default implementation is Date.toISOString.
88
87
  * See also Culture.setDefaultDateEncoding.
@@ -27,6 +27,7 @@ import {
27
27
  } from "../overlay/tooltip-ops";
28
28
  import { Field, getFieldTooltip } from "./Field";
29
29
  import { MonthPicker } from "./MonthPicker";
30
+ import { getActiveElement } from "../../util/getActiveElement";
30
31
 
31
32
  export class MonthField extends Field {
32
33
  declareData() {
@@ -63,7 +64,7 @@ export class MonthField extends Field {
63
64
  maxExclusive: undefined,
64
65
  icon: undefined,
65
66
  },
66
- ...arguments
67
+ ...arguments,
67
68
  );
68
69
  }
69
70
 
@@ -163,6 +164,7 @@ export class MonthField extends Field {
163
164
  }}
164
165
  label={this.labelPlacement && getContent(this.renderLabel(context, instance, "label"))}
165
166
  help={this.helpPlacement && getContent(this.renderHelp(context, instance, "help"))}
167
+ icon={this.renderIcon(context, instance, "icon")}
166
168
  />
167
169
  );
168
170
  }
@@ -261,7 +263,7 @@ class MonthInput extends VDOM.Component {
261
263
  }
262
264
 
263
265
  render() {
264
- var { instance, label, help, data } = this.props;
266
+ var { instance, label, help, data, icon: iconVDOM } = this.props;
265
267
  var { widget, state } = instance;
266
268
  var { CSS, baseClass, suppressErrorsUntilVisited } = widget;
267
269
 
@@ -294,12 +296,8 @@ class MonthInput extends VDOM.Component {
294
296
  );
295
297
  }
296
298
 
297
- if (data.icon) {
298
- icon = (
299
- <div className={CSS.element(baseClass, "left-icon")}>
300
- {Icon.render(data.icon, { className: CSS.element(baseClass, "icon") })}
301
- </div>
302
- );
299
+ if (iconVDOM) {
300
+ icon = <div className={CSS.element(baseClass, "left-icon")}>{iconVDOM}</div>;
303
301
  }
304
302
 
305
303
  var dropdown = false;
@@ -325,7 +323,7 @@ class MonthInput extends VDOM.Component {
325
323
  icon: !!icon,
326
324
  empty: empty && !data.placeholder,
327
325
  error: data.error && (state.visited || !suppressErrorsUntilVisited || !empty),
328
- })
326
+ }),
329
327
  )}
330
328
  style={data.style}
331
329
  onMouseDown={this.onMouseDown.bind(this)}
@@ -345,8 +343,8 @@ class MonthInput extends VDOM.Component {
345
343
  readOnly={data.readOnly}
346
344
  tabIndex={data.tabIndex}
347
345
  placeholder={data.placeholder}
348
- onInput={(e) => this.onChange(e, "input")}
349
- onChange={(e) => this.onChange(e, "change")}
346
+ onInput={(e) => this.onChange(e.target.value, "input")}
347
+ onChange={(e) => this.onChange(e.target.value, "change")}
350
348
  onKeyDown={(e) => this.onKeyDown(e)}
351
349
  onBlur={(e) => {
352
350
  this.onBlur(e);
@@ -400,7 +398,7 @@ class MonthInput extends VDOM.Component {
400
398
  switch (e.keyCode) {
401
399
  case KeyCode.enter:
402
400
  e.stopPropagation();
403
- this.onChange(e, "enter");
401
+ this.onChange(e.target.value, "enter");
404
402
  break;
405
403
 
406
404
  case KeyCode.esc:
@@ -432,7 +430,7 @@ class MonthInput extends VDOM.Component {
432
430
  this.setState({
433
431
  focus: false,
434
432
  });
435
- this.onChange(e, "blur");
433
+ this.onChange(e.target.value, "blur");
436
434
  }
437
435
 
438
436
  closeDropdown(e, callback) {
@@ -487,16 +485,19 @@ class MonthInput extends VDOM.Component {
487
485
  }
488
486
 
489
487
  componentWillUnmount() {
488
+ if (this.input == getActiveElement()) {
489
+ this.onChange(this.input.value, "blur");
490
+ }
490
491
  tooltipParentWillUnmount(this.props.instance);
491
492
  }
492
493
 
493
- onChange(e, eventType) {
494
+ onChange(inputValue, eventType) {
494
495
  var { instance } = this.props;
495
496
  var { widget } = instance;
496
497
 
497
498
  if (widget.reactOn.indexOf(eventType) == -1) return;
498
499
 
499
- var parts = e.target.value.split("-");
500
+ var parts = inputValue.split("-");
500
501
  var date1 = widget.parseDate(parts[0]);
501
502
  var date2 = widget.parseDate(parts[1]) || date1;
502
503
 
@@ -51,8 +51,8 @@ interface NumberFieldProps extends FieldProps {
51
51
  /** Round values to the nearest tick. Default is `true`. */
52
52
  snapToIncrement?: boolean;
53
53
 
54
- /** Name of the icon to be put on the left side of the input. */
55
- icon?: string;
54
+ /** Name or configuration of the icon to be put on the left side of the input. */
55
+ icon?: Cx.StringProp | Cx.Record;
56
56
 
57
57
  /** Set to `false` to hide the clear button. It can be used interchangeably with the `hideClear` property. Default value is `true`. */
58
58
  showClear?: boolean;
@@ -11,12 +11,12 @@ import {
11
11
  tooltipParentDidMount,
12
12
  } from "../overlay/tooltip-ops";
13
13
  import { stopPropagation } from "../../util/eventCallbacks";
14
- import { Icon } from "../Icon";
15
14
  import { Localization } from "../../ui/Localization";
16
15
  import ClearIcon from "../icons/clear";
17
16
  import { isString } from "../../util/isString";
18
17
  import { isNumber } from "../../util/isNumber";
19
18
  import { isDefined } from "../../util/isDefined";
19
+ import { getActiveElement } from "../../util/getActiveElement";
20
20
 
21
21
  import { enableCultureSensitiveFormatting } from "../../ui/Format";
22
22
  import { KeyCode } from "../../util/KeyCode";
@@ -46,7 +46,7 @@ export class NumberField extends Field {
46
46
  scale: undefined,
47
47
  offset: undefined,
48
48
  },
49
- ...arguments
49
+ ...arguments,
50
50
  );
51
51
  }
52
52
 
@@ -110,6 +110,7 @@ export class NumberField extends Field {
110
110
  instance={instance}
111
111
  label={this.labelPlacement && getContent(this.renderLabel(context, instance, "label"))}
112
112
  help={this.helpPlacement && getContent(this.renderHelp(context, instance, "help"))}
113
+ icon={this.renderIcon(context, instance, "icon")}
113
114
  />
114
115
  );
115
116
  }
@@ -151,15 +152,11 @@ class Input extends VDOM.Component {
151
152
  }
152
153
 
153
154
  render() {
154
- let { data, instance, label, help } = this.props;
155
+ let { data, instance, label, help, icon: iconVDOM } = this.props;
155
156
  let { widget, state } = instance;
156
157
  let { CSS, baseClass, suppressErrorsUntilVisited } = widget;
157
158
 
158
- let icon = data.icon && (
159
- <div className={CSS.element(baseClass, "left-icon")}>
160
- {Icon.render(data.icon, { className: CSS.element(baseClass, "icon") })}
161
- </div>
162
- );
159
+ let icon = iconVDOM && <div className={CSS.element(baseClass, "left-icon")}>{iconVDOM}</div>;
163
160
 
164
161
  let insideButton;
165
162
  if (!data.readOnly && !data.disabled) {
@@ -190,7 +187,7 @@ class Input extends VDOM.Component {
190
187
  icon: !!icon,
191
188
  empty: empty && !data.placeholder,
192
189
  error: data.error && (state.visited || !suppressErrorsUntilVisited || !empty),
193
- })
190
+ }),
194
191
  )}
195
192
  style={data.style}
196
193
  onMouseDown={stopPropagation}
@@ -252,6 +249,9 @@ class Input extends VDOM.Component {
252
249
  }
253
250
 
254
251
  componentWillUnmount() {
252
+ if (this.input == getActiveElement()) {
253
+ this.onChange({ target: { value: this.input.value } }, "blur");
254
+ }
255
255
  tooltipParentWillUnmount(this.props.instance);
256
256
  }
257
257
 
@@ -413,12 +413,12 @@ class Input extends VDOM.Component {
413
413
  let decimalSeparator = this.getDecimalSeparator(fmt) || Format.value(1.1, "n;1")[1];
414
414
 
415
415
  let formatted = Format.value(value, fmt);
416
- //re-parse to avoid differences between formatted value and value in the store
416
+ // Re-parse to avoid differences between formatted value and value in the store
417
417
 
418
418
  value = widget.parseValue(formatted, instance) * data.scale + data.offset;
419
419
 
420
- //allow users to type numbers like 100.0003 or -0.05 without interruptions
421
- //if the last typed in character is zero or dot (decimal separator) skip processing it
420
+ // Allow users to type numbers like 100.0003 or -0.05 without interruptions
421
+ // If the last typed character is zero or dot (decimal separator), skip processing it
422
422
  if (
423
423
  change == "change" &&
424
424
  this.input.selectionStart == this.input.selectionEnd &&
@@ -430,7 +430,7 @@ class Input extends VDOM.Component {
430
430
  return;
431
431
 
432
432
  if (change != "blur") {
433
- //format, but keep the correct cursor position
433
+ // Format, but keep the correct cursor position
434
434
  let preCursorText = this.getPreCursorDigits(this.input.value, this.input.selectionStart, decimalSeparator);
435
435
  this.input.value = formatted;
436
436
  this.updateCursorPosition(preCursorText);
@@ -1,73 +1,69 @@
1
- import * as Cx from '../../core';
2
- import { FieldProps } from './Field';
1
+ import * as Cx from "../../core";
2
+ import { FieldProps } from "./Field";
3
3
 
4
4
  interface SelectProps extends FieldProps {
5
-
6
5
  /** Select value. */
7
- value?: Cx.Prop<number | string>,
6
+ value?: Cx.Prop<number | string>;
8
7
 
9
8
  /** Value when no selection is made. Default is `undefined` */
10
- emptyValue?: any,
9
+ emptyValue?: any;
11
10
 
12
11
  /** The opposite of `disabled`. */
13
- enabled?: Cx.BooleanProp,
12
+ enabled?: Cx.BooleanProp;
14
13
 
15
14
  /** Default text displayed when the field is empty. */
16
- placeholder?: Cx.StringProp,
17
-
18
- /**
19
- * Set to `true` to hide the clear button. It can be used interchangeably with the `showClear` property. Default value is `false`.
20
- * Note, the `placeholder` needs to be specified for the clear button to render.
15
+ placeholder?: Cx.StringProp;
16
+
17
+ /**
18
+ * Set to `true` to hide the clear button. It can be used interchangeably with the `showClear` property. Default value is `false`.
19
+ * Note, the `placeholder` needs to be specified for the clear button to render.
21
20
  */
22
- hideClear?: boolean,
23
-
21
+ hideClear?: boolean;
22
+
24
23
  /**
25
- * Set to `false` to hide the clear button. It can be used interchangeably with the `hideClear` property. Default value is `true`.
26
- * Note, the `placeholder` needs to be specified for the clear button to render.
24
+ * Set to `false` to hide the clear button. It can be used interchangeably with the `hideClear` property. Default value is `true`.
25
+ * Note, the `placeholder` needs to be specified for the clear button to render.
27
26
  */
28
- showClear?: boolean,
27
+ showClear?: boolean;
29
28
 
30
29
  /**
31
30
  * Set to `true` to display the clear button even if `required` is set. Default is `false`.
32
31
  */
33
- alwaysShowClear?: boolean,
34
-
32
+ alwaysShowClear?: boolean;
33
+
35
34
  /** Base CSS class to be applied to the element. Defaults to `select`. */
36
- baseClass?: string,
35
+ baseClass?: string;
37
36
 
38
37
  /** Defaults to `false`. Set to `true` to enable multiple selection. */
39
- multiple?: boolean,
38
+ multiple?: boolean;
40
39
 
41
- /**
42
- * Convert values before selection.
43
- * Useful for converting strings into numbers. Default is `true`.
40
+ /**
41
+ * Convert values before selection.
42
+ * Useful for converting strings into numbers. Default is `true`.
44
43
  */
45
- convertValues?: boolean,
46
-
44
+ convertValues?: boolean;
45
+
47
46
  /** String value used to indicate a `null` entry */
48
- nullString?: string,
49
-
50
- /** Name of the icon to be put on the left side of the input. */
51
- icon?: string
47
+ nullString?: string;
52
48
 
49
+ /** Name or configuration of the icon to be put on the left side of the input. */
50
+ icon?: Cx.StringProp | Cx.Record;
53
51
  }
54
52
 
55
53
  export class Select extends Cx.Widget<SelectProps> {}
56
54
 
57
55
  interface OptionProps extends Cx.HtmlElementProps {
58
-
59
56
  /** Value property. */
60
- value?: Cx.StringProp,
57
+ value?: Cx.StringProp;
61
58
 
62
59
  /** Defaults to `false`. Set to `true` to disable the field. */
63
- disabled?: Cx.BooleanProp,
60
+ disabled?: Cx.BooleanProp;
64
61
 
65
62
  /** The opposite of `disabled`. */
66
- enabled?: Cx.BooleanProp,
63
+ enabled?: Cx.BooleanProp;
67
64
 
68
65
  /** Defaults to `false`. Set to `true` to select the the option. */
69
- selected?: Cx.BooleanProp,
70
-
66
+ selected?: Cx.BooleanProp;
71
67
  }
72
68
 
73
69
  export class Option extends Cx.Widget<OptionProps> {}
@@ -3,7 +3,6 @@ import { HtmlElement } from "../HtmlElement";
3
3
  import { Field, getFieldTooltip } from "./Field";
4
4
  import {
5
5
  tooltipParentWillReceiveProps,
6
- tooltipParentWillUnmount,
7
6
  tooltipMouseMove,
8
7
  tooltipMouseLeave,
9
8
  tooltipParentDidMount,
@@ -11,7 +10,6 @@ import {
11
10
  import { stopPropagation, preventDefault } from "../../util/eventCallbacks";
12
11
  import DropdownIcon from "../icons/drop-down";
13
12
  import ClearIcon from "../icons/clear";
14
- import { Icon } from "../Icon";
15
13
  import { Localization } from "../../ui/Localization";
16
14
  import { isString } from "../../util/isString";
17
15
  import { isDefined } from "../../util/isDefined";
@@ -29,7 +27,7 @@ export class Select extends Field {
29
27
  placeholder: undefined,
30
28
  icon: undefined,
31
29
  },
32
- ...arguments
30
+ ...arguments,
33
31
  );
34
32
  }
35
33
 
@@ -48,6 +46,7 @@ export class Select extends Field {
48
46
  select={(v) => this.select(v, instance)}
49
47
  label={this.labelPlacement && getContent(this.renderLabel(context, instance, "label"))}
50
48
  help={this.helpPlacement && getContent(this.renderHelp(context, instance, "help"))}
49
+ icon={this.renderIcon(context, instance, "icon")}
51
50
  >
52
51
  {this.renderChildren(context, instance)}
53
52
  </SelectComponent>
@@ -95,15 +94,11 @@ class SelectComponent extends VDOM.Component {
95
94
  }
96
95
 
97
96
  render() {
98
- let { multiple, select, instance, label, help } = this.props;
97
+ let { multiple, select, instance, label, help, icon: iconVDOM } = this.props;
99
98
  let { data, widget, state } = instance;
100
99
  let { CSS, baseClass } = widget;
101
100
 
102
- let icon = data.icon && (
103
- <div className={CSS.element(baseClass, "left-icon")}>
104
- {Icon.render(data.icon, { className: CSS.element(baseClass, "icon") })}
105
- </div>
106
- );
101
+ let icon = iconVDOM && <div className={CSS.element(baseClass, "left-icon")}>{iconVDOM}</div>;
107
102
 
108
103
  let insideButton,
109
104
  readOnly = data.disabled || data.readOnly;
@@ -148,11 +143,11 @@ class SelectComponent extends VDOM.Component {
148
143
  data.classNames,
149
144
  CSS.state({
150
145
  visited: state.visited,
151
- icon: data.icon,
146
+ icon: !!iconVDOM,
152
147
  focus: this.state.focus,
153
148
  error: state.visited && data.error,
154
149
  empty: data.empty && !data.placeholder,
155
- })
150
+ }),
156
151
  )}
157
152
  style={data.style}
158
153
  onMouseDown={stopPropagation}
@@ -252,7 +247,7 @@ export class Option extends HtmlElement {
252
247
  selected: undefined,
253
248
  text: undefined,
254
249
  },
255
- ...arguments
250
+ ...arguments,
256
251
  );
257
252
  }
258
253
 
@@ -11,6 +11,7 @@ import {
11
11
  import { stopPropagation } from "../../util/eventCallbacks";
12
12
  import { KeyCode } from "../../util/KeyCode";
13
13
  import { autoFocus } from "../autoFocus";
14
+ import { getActiveElement } from "../../util/getActiveElement";
14
15
 
15
16
  export class TextArea extends TextField {
16
17
  declareData() {
@@ -93,10 +94,10 @@ class Input extends VDOM.Component {
93
94
  tabIndex={data.tabIndex}
94
95
  placeholder={data.placeholder}
95
96
  {...data.inputAttrs}
96
- onInput={(e) => this.onChange(e, "input")}
97
- onChange={(e) => this.onChange(e, "change")}
97
+ onInput={(e) => this.onChange(e.target.value, "input")}
98
+ onChange={(e) => this.onChange(e.target.value, "change")}
98
99
  onBlur={(e) => {
99
- this.onChange(e, "blur");
100
+ this.onChange(e.target.value, "blur");
100
101
  }}
101
102
  onFocus={(e) => this.onFocus()}
102
103
  onClick={stopPropagation}
@@ -111,6 +112,9 @@ class Input extends VDOM.Component {
111
112
  }
112
113
 
113
114
  componentWillUnmount() {
115
+ if (this.input == getActiveElement()) {
116
+ this.onChange(this.input.value, "blur");
117
+ }
114
118
  tooltipParentWillUnmount(this.props.instance);
115
119
  }
116
120
 
@@ -144,7 +148,7 @@ class Input extends VDOM.Component {
144
148
  tooltipParentWillReceiveProps(this.input, ...getFieldTooltip(instance));
145
149
  }
146
150
 
147
- onChange(e, change) {
151
+ onChange(inputValue, change) {
148
152
  let { instance, data } = this.props;
149
153
  let { widget } = instance;
150
154
 
@@ -158,12 +162,12 @@ class Input extends VDOM.Component {
158
162
 
159
163
  if (data.required) {
160
164
  instance.setState({
161
- empty: !e.target.value,
165
+ empty: !inputValue,
162
166
  });
163
167
  }
164
168
 
165
169
  if (instance.widget.reactOn.indexOf(change) != -1) {
166
- let value = e.target.value || widget.emptyValue;
170
+ let value = inputValue || widget.emptyValue;
167
171
  instance.set("value", value);
168
172
  }
169
173
  }
@@ -63,8 +63,8 @@ export interface TextFieldProps extends FieldProps {
63
63
  /** Regular expression used to validate the user's input. */
64
64
  validationRegExp?: RegExp;
65
65
 
66
- /** Name of the icon to be put on the left side of the input. */
67
- icon?: Cx.StringProp;
66
+ /** Name or configuration of the icon to be put on the left side of the input. */
67
+ icon?: Cx.StringProp | Cx.Record;
68
68
 
69
69
  /** If trackFocus is set, this value will be set when the field receives or loses focus. */
70
70
  focused?: Cx.BooleanProp;