cx 26.1.13 → 26.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 (127) hide show
  1. package/build/charts/Marker.d.ts +1 -1
  2. package/build/charts/Marker.d.ts.map +1 -1
  3. package/build/charts/Marker.js +16 -6
  4. package/build/charts/MouseTracker.d.ts +2 -0
  5. package/build/charts/MouseTracker.d.ts.map +1 -1
  6. package/build/charts/helpers/PointReducer.d.ts +2 -2
  7. package/build/charts/helpers/PointReducer.d.ts.map +1 -1
  8. package/build/data/View.d.ts +5 -3
  9. package/build/data/View.d.ts.map +1 -1
  10. package/build/data/View.js +3 -1
  11. package/build/data/ops/findTreeNode.d.ts +20 -1
  12. package/build/data/ops/findTreeNode.d.ts.map +1 -1
  13. package/build/data/ops/findTreeNode.js +19 -0
  14. package/build/data/ops/findTreePath.d.ts +1 -1
  15. package/build/data/ops/findTreePath.d.ts.map +1 -1
  16. package/build/data/ops/findTreePath.js +1 -1
  17. package/build/data/ops/removeTreeNodes.d.ts +14 -1
  18. package/build/data/ops/removeTreeNodes.d.ts.map +1 -1
  19. package/build/data/ops/removeTreeNodes.js +13 -0
  20. package/build/data/ops/updateArray.d.ts +1 -1
  21. package/build/data/ops/updateArray.d.ts.map +1 -1
  22. package/build/data/ops/updateArray.js +1 -1
  23. package/build/data/ops/updateTree.d.ts +20 -1
  24. package/build/data/ops/updateTree.d.ts.map +1 -1
  25. package/build/data/ops/updateTree.js +19 -0
  26. package/build/jsx-runtime.d.ts +1 -0
  27. package/build/jsx-runtime.d.ts.map +1 -1
  28. package/build/jsx-runtime.js +3 -1
  29. package/build/svg/Rectangle.d.ts +6 -4
  30. package/build/svg/Rectangle.d.ts.map +1 -1
  31. package/build/svg/Rectangle.js +9 -7
  32. package/build/ui/Instance.d.ts +1 -1
  33. package/build/ui/Instance.d.ts.map +1 -1
  34. package/build/ui/Instance.js +18 -8
  35. package/build/ui/IsolatedScope.d.ts +2 -1
  36. package/build/ui/IsolatedScope.d.ts.map +1 -1
  37. package/build/ui/Prop.d.ts +1 -1
  38. package/build/ui/Prop.d.ts.map +1 -1
  39. package/build/ui/Widget.d.ts +2 -0
  40. package/build/ui/Widget.d.ts.map +1 -1
  41. package/build/ui/Widget.js +4 -0
  42. package/build/ui/adapter/GroupAdapter.d.ts +4 -4
  43. package/build/ui/adapter/GroupAdapter.d.ts.map +1 -1
  44. package/build/ui/adapter/GroupAdapter.js +4 -4
  45. package/build/ui/adapter/TreeAdapter.d.ts +5 -3
  46. package/build/ui/adapter/TreeAdapter.d.ts.map +1 -1
  47. package/build/ui/adapter/TreeAdapter.js +12 -5
  48. package/build/ui/app/startAppLoop.d.ts +2 -2
  49. package/build/ui/app/startAppLoop.d.ts.map +1 -1
  50. package/build/ui/app/startHotAppLoop.d.ts +4 -4
  51. package/build/ui/app/startHotAppLoop.d.ts.map +1 -1
  52. package/build/ui/app/startHotAppLoop.js +1 -1
  53. package/build/ui/batchUpdates.d.ts.map +1 -1
  54. package/build/ui/batchUpdates.js +3 -4
  55. package/build/widgets/Button.d.ts +0 -7
  56. package/build/widgets/Button.d.ts.map +1 -1
  57. package/build/widgets/HtmlElement.d.ts +2 -2
  58. package/build/widgets/HtmlElement.d.ts.map +1 -1
  59. package/build/widgets/form/Checkbox.d.ts +3 -3
  60. package/build/widgets/form/Checkbox.d.ts.map +1 -1
  61. package/build/widgets/form/Checkbox.js +11 -6
  62. package/build/widgets/form/DateTimeField.d.ts +4 -0
  63. package/build/widgets/form/DateTimeField.d.ts.map +1 -1
  64. package/build/widgets/form/TextField.d.ts +2 -2
  65. package/build/widgets/form/TextField.d.ts.map +1 -1
  66. package/build/widgets/grid/Grid.d.ts +20 -16
  67. package/build/widgets/grid/Grid.d.ts.map +1 -1
  68. package/build/widgets/grid/Grid.js +200 -86
  69. package/build/widgets/nav/Menu.d.ts +2 -0
  70. package/build/widgets/nav/Menu.d.ts.map +1 -1
  71. package/build/widgets/nav/Route.js +1 -1
  72. package/build/widgets/overlay/FlyweightTooltipTracker.d.ts +6 -4
  73. package/build/widgets/overlay/FlyweightTooltipTracker.d.ts.map +1 -1
  74. package/build/widgets/overlay/FlyweightTooltipTracker.js +3 -0
  75. package/build/widgets/overlay/Overlay.d.ts +2 -2
  76. package/build/widgets/overlay/Overlay.d.ts.map +1 -1
  77. package/dist/data.js +52 -1
  78. package/dist/jsx-runtime.js +4 -2
  79. package/dist/manifest.js +910 -904
  80. package/dist/svg.js +3 -0
  81. package/dist/ui.js +1548 -1544
  82. package/dist/widgets.css +1 -1
  83. package/dist/widgets.js +395 -4
  84. package/package.json +2 -2
  85. package/src/charts/Marker.tsx +448 -394
  86. package/src/charts/MouseTracker.tsx +3 -0
  87. package/src/charts/helpers/PointReducer.ts +2 -2
  88. package/src/data/View.ts +76 -19
  89. package/src/data/ops/findTreeNode.ts +20 -1
  90. package/src/data/ops/findTreePath.ts +7 -2
  91. package/src/data/ops/removeTreeNodes.ts +14 -1
  92. package/src/data/ops/updateArray.ts +4 -4
  93. package/src/data/ops/updateTree.ts +32 -6
  94. package/src/index.scss +6 -6
  95. package/src/jsx-runtime.spec.tsx +40 -0
  96. package/src/jsx-runtime.ts +87 -84
  97. package/src/svg/Rectangle.tsx +80 -73
  98. package/src/ui/DataProxy.ts +55 -55
  99. package/src/ui/Instance.ts +142 -45
  100. package/src/ui/IsolatedScope.ts +4 -2
  101. package/src/ui/Prop.ts +141 -141
  102. package/src/ui/Rescope.ts +50 -50
  103. package/src/ui/Widget.tsx +292 -234
  104. package/src/ui/adapter/ArrayAdapter.ts +229 -229
  105. package/src/ui/adapter/GroupAdapter.ts +8 -10
  106. package/src/ui/adapter/TreeAdapter.ts +75 -15
  107. package/src/ui/app/Url.spec.ts +1 -1
  108. package/src/ui/app/startAppLoop.tsx +56 -45
  109. package/src/ui/app/startHotAppLoop.ts +4 -4
  110. package/src/ui/batchUpdates.ts +16 -21
  111. package/src/ui/exprHelpers.ts +96 -96
  112. package/src/widgets/Button.tsx +0 -8
  113. package/src/widgets/HtmlElement.spec.tsx +100 -72
  114. package/src/widgets/HtmlElement.tsx +11 -10
  115. package/src/widgets/Sandbox.ts +104 -104
  116. package/src/widgets/Section.scss +55 -55
  117. package/src/widgets/drag-drop/DropZone.scss +74 -74
  118. package/src/widgets/form/Checkbox.tsx +296 -243
  119. package/src/widgets/form/DateTimeField.tsx +6 -0
  120. package/src/widgets/form/TextField.tsx +2 -2
  121. package/src/widgets/grid/Grid.scss +43 -10
  122. package/src/widgets/grid/Grid.tsx +4401 -3848
  123. package/src/widgets/nav/Menu.tsx +3 -0
  124. package/src/widgets/nav/Route.ts +1 -1
  125. package/src/widgets/overlay/FlyweightTooltipTracker.ts +15 -4
  126. package/src/widgets/overlay/Overlay.tsx +2 -1
  127. package/src/widgets/overlay/index.d.ts +11 -11
@@ -10,193 +10,234 @@ import CheckIcon from "../icons/check";
10
10
  import SquareIcon from "../icons/square";
11
11
  import { tooltipMouseLeave, tooltipMouseMove } from "../overlay/tooltip-ops";
12
12
  import { Field, FieldConfig, getFieldTooltip, FieldInstance } from "./Field";
13
- import { BooleanProp, StringProp } from "../../ui/Prop";
13
+ import { BooleanProp, Prop, StringProp } from "../../ui/Prop";
14
14
 
15
15
  export interface CheckboxConfig extends FieldConfig {
16
- /** Value of the checkbox. */
17
- value?: BooleanProp;
16
+ /** Value of the checkbox. */
17
+ value?: Prop<boolean | null>;
18
18
 
19
- /** Set to `true` to make the checkbox read-only. */
20
- readOnly?: BooleanProp;
19
+ /** Set to `true` to make the checkbox read-only. */
20
+ readOnly?: BooleanProp;
21
21
 
22
- /** Base CSS class to be applied to the element. Defaults to `checkbox`. */
23
- baseClass?: string;
22
+ /** Base CSS class to be applied to the element. Defaults to `checkbox`. */
23
+ baseClass?: string;
24
24
 
25
- /** Use native checkbox HTML element. */
26
- native?: boolean;
25
+ /** Use native checkbox HTML element. */
26
+ native?: boolean;
27
27
 
28
- /** Set to `true` to display a square icon to indicate `null` or `undefined` value. */
29
- indeterminate?: boolean;
28
+ /** Set to `true` to display a square icon to indicate `null` or `undefined` value. */
29
+ indeterminate?: boolean;
30
30
 
31
- /** Checked value alias for `value`. */
32
- checked?: BooleanProp;
31
+ /** Checked value alias for `value`. */
32
+ checked?: Prop<boolean | null>;
33
33
 
34
- /** Text description. */
35
- text?: StringProp;
34
+ /** Text description. */
35
+ text?: StringProp;
36
36
 
37
- /** Set to true to disable focusing on the checkbox. Used in grids to avoid conflicts. */
38
- unfocusable?: boolean;
37
+ /** Set to true to disable focusing on the checkbox. Used in grids to avoid conflicts. */
38
+ unfocusable?: boolean;
39
39
 
40
- /** View mode text. */
41
- viewText?: StringProp;
40
+ /** View mode text. */
41
+ viewText?: StringProp;
42
42
 
43
- /** Custom validation function. */
44
- onValidate?: string | ((value: boolean, instance: Instance, validationParams: Record<string, unknown>) => unknown);
43
+ /** Custom validation function. */
44
+ onValidate?:
45
+ | string
46
+ | ((
47
+ value: boolean,
48
+ instance: Instance,
49
+ validationParams: Record<string, unknown>,
50
+ ) => unknown);
45
51
  }
46
52
 
47
53
  export class Checkbox extends Field<CheckboxConfig> {
48
- declare public baseClass: string;
49
- declare public checked?: unknown;
50
- declare public value?: unknown;
51
- declare public indeterminate?: boolean;
52
- declare public unfocusable?: boolean;
53
- declare public native?: boolean;
54
-
55
- constructor(config?: CheckboxConfig) {
56
- super(config);
57
- }
58
-
59
- init(): void {
60
- if (this.checked) this.value = this.checked;
61
-
62
- super.init();
63
- }
64
-
65
- declareData(...args: Record<string, unknown>[]): void {
66
- super.declareData(
67
- {
68
- value: !this.indeterminate ? false : undefined,
69
- text: undefined,
70
- readOnly: undefined,
71
- disabled: undefined,
72
- enabled: undefined,
73
- required: undefined,
74
- viewText: undefined,
75
- },
76
- ...args,
77
- );
78
- }
79
-
80
- renderWrap(
81
- context: RenderingContext,
82
- instance: FieldInstance<Checkbox>,
83
- key: string,
84
- content: React.ReactNode,
85
- ): React.ReactElement {
86
- let { data } = instance;
87
- return (
88
- <label
89
- key={key}
90
- className={data.classNames}
91
- onMouseDown={(e) => {
92
- e.stopPropagation();
93
- if (this.unfocusable) e.preventDefault();
94
- }}
95
- onMouseMove={(e) => {
96
- const tooltip = getFieldTooltip(instance);
97
- if (Array.isArray(tooltip)) {
98
- tooltipMouseMove(e, ...tooltip);
99
- }
100
- }}
101
- onMouseLeave={(e) => {
102
- const tooltip = getFieldTooltip(instance);
103
- if (Array.isArray(tooltip)) {
104
- tooltipMouseLeave(e, ...tooltip);
105
- }
106
- }}
107
- onClick={(e) => {
108
- this.handleClick(e, instance);
109
- }}
110
- style={data.style}
111
- >
112
- {content}
113
- {this.labelPlacement && getContent(this.renderLabel(context, instance, "label"))}
114
- </label>
115
- );
116
- }
117
-
118
- validateRequired(context: RenderingContext, instance: FieldInstance<Checkbox>): string | undefined {
119
- let { data } = instance;
120
- if (!data.value) return this.requiredText;
121
- }
122
-
123
- renderNativeCheck(context: RenderingContext, instance: FieldInstance<Checkbox>): React.ReactElement {
124
- let { CSS, baseClass } = this;
125
- let { data } = instance;
126
- return (
127
- <input
128
- key="input"
129
- className={CSS.element(baseClass, "checkbox")}
130
- id={data.id}
131
- type="checkbox"
132
- checked={data.value || false}
133
- disabled={data.disabled}
134
- {...data.inputAttrs}
135
- onClick={stopPropagation}
136
- onChange={(e) => {
137
- this.handleChange(e, instance, (e.target as HTMLInputElement).checked);
138
- }}
139
- />
140
- );
141
- }
142
-
143
- renderCheck(context: RenderingContext, instance: FieldInstance<Checkbox>): React.ReactElement {
144
- return <CheckboxCmp key="check" instance={instance} data={instance.data} />;
145
- }
146
-
147
- renderInput(context: RenderingContext, instance: FieldInstance<Checkbox>, key: string): React.ReactElement {
148
- let { data } = instance;
149
- let text = data.text || this.renderChildren?.(context, instance);
150
- let { CSS, baseClass } = this;
151
- return this.renderWrap(context, instance, key, [
152
- this.native ? this.renderNativeCheck(context, instance) : this.renderCheck(context, instance),
153
- text ? (
154
- <div key="text" className={CSS.element(baseClass, "text")}>
155
- {text}
156
- </div>
157
- ) : (
158
- <span key="baseline" className={CSS.element(baseClass, "baseline")}>
159
- &nbsp;
160
- </span>
161
- ),
162
- ]);
163
- }
164
-
165
- renderValue(context: RenderingContext, instance: FieldInstance): React.ReactNode {
166
- let { data } = instance;
167
- if (!data.viewText) return super.renderValue(context, instance, undefined);
168
- return <span className={this.CSS.element(this.baseClass, "view-text")}>{data.viewText}</span>;
169
- }
170
-
171
- formatValue(context: RenderingContext, instance: Instance): React.ReactNode | string {
172
- let { data } = instance;
173
- return data.value && (data.text || this.renderChildren?.(context, instance));
174
- }
175
-
176
- handleClick(e: React.MouseEvent, instance: Instance): void {
177
- if (this.native) e.stopPropagation();
178
- else {
179
- var el = document.getElementById(instance.data.id);
180
- if (el) el.focus();
181
- if (!instance.data.viewMode) {
182
- e.preventDefault();
183
- e.stopPropagation();
184
- this.handleChange(e, instance, !instance.data.value);
185
- }
54
+ declare public baseClass: string;
55
+ declare public checked?: unknown;
56
+ declare public value?: unknown;
57
+ declare public indeterminate?: boolean;
58
+ declare public unfocusable?: boolean;
59
+ declare public native?: boolean;
60
+
61
+ constructor(config?: CheckboxConfig) {
62
+ super(config);
63
+ }
64
+
65
+ init(): void {
66
+ if (this.checked) this.value = this.checked;
67
+
68
+ super.init();
69
+ }
70
+
71
+ declareData(...args: Record<string, unknown>[]): void {
72
+ super.declareData(
73
+ {
74
+ value: !this.indeterminate ? false : undefined,
75
+ text: undefined,
76
+ readOnly: undefined,
77
+ disabled: undefined,
78
+ enabled: undefined,
79
+ required: undefined,
80
+ viewText: undefined,
81
+ },
82
+ ...args,
83
+ );
84
+ }
85
+
86
+ renderWrap(
87
+ context: RenderingContext,
88
+ instance: FieldInstance<Checkbox>,
89
+ key: string,
90
+ content: React.ReactNode,
91
+ ): React.ReactElement {
92
+ let { data } = instance;
93
+ return (
94
+ <label
95
+ key={key}
96
+ className={data.classNames}
97
+ onMouseDown={(e) => {
98
+ e.stopPropagation();
99
+ if (this.unfocusable) e.preventDefault();
100
+ }}
101
+ onMouseMove={(e) => {
102
+ const tooltip = getFieldTooltip(instance);
103
+ if (Array.isArray(tooltip)) {
104
+ tooltipMouseMove(e, ...tooltip);
105
+ }
106
+ }}
107
+ onMouseLeave={(e) => {
108
+ const tooltip = getFieldTooltip(instance);
109
+ if (Array.isArray(tooltip)) {
110
+ tooltipMouseLeave(e, ...tooltip);
111
+ }
112
+ }}
113
+ onClick={(e) => {
114
+ this.handleClick(e, instance);
115
+ }}
116
+ style={data.style}
117
+ >
118
+ {content}
119
+ {this.labelPlacement &&
120
+ getContent(this.renderLabel(context, instance, "label"))}
121
+ </label>
122
+ );
123
+ }
124
+
125
+ validateRequired(
126
+ context: RenderingContext,
127
+ instance: FieldInstance<Checkbox>,
128
+ ): string | undefined {
129
+ let { data } = instance;
130
+ if (!data.value) return this.requiredText;
131
+ }
132
+
133
+ renderNativeCheck(
134
+ context: RenderingContext,
135
+ instance: FieldInstance<Checkbox>,
136
+ ): React.ReactElement {
137
+ let { CSS, baseClass } = this;
138
+ let { data } = instance;
139
+ return (
140
+ <input
141
+ key="input"
142
+ className={CSS.element(baseClass, "checkbox")}
143
+ id={data.id}
144
+ type="checkbox"
145
+ checked={data.value || false}
146
+ disabled={data.disabled}
147
+ {...data.inputAttrs}
148
+ onClick={stopPropagation}
149
+ onChange={(e) => {
150
+ this.handleChange(
151
+ e,
152
+ instance,
153
+ (e.target as HTMLInputElement).checked,
154
+ );
155
+ }}
156
+ />
157
+ );
158
+ }
159
+
160
+ renderCheck(
161
+ context: RenderingContext,
162
+ instance: FieldInstance<Checkbox>,
163
+ ): React.ReactElement {
164
+ return <CheckboxCmp key="check" instance={instance} data={instance.data} />;
165
+ }
166
+
167
+ renderInput(
168
+ context: RenderingContext,
169
+ instance: FieldInstance<Checkbox>,
170
+ key: string,
171
+ ): React.ReactElement {
172
+ let { data } = instance;
173
+ let text = data.text || this.renderChildren?.(context, instance);
174
+ let { CSS, baseClass } = this;
175
+ return this.renderWrap(context, instance, key, [
176
+ this.native
177
+ ? this.renderNativeCheck(context, instance)
178
+ : this.renderCheck(context, instance),
179
+ text ? (
180
+ <div key="text" className={CSS.element(baseClass, "text")}>
181
+ {text}
182
+ </div>
183
+ ) : (
184
+ <span key="baseline" className={CSS.element(baseClass, "baseline")}>
185
+ &nbsp;
186
+ </span>
187
+ ),
188
+ ]);
189
+ }
190
+
191
+ renderValue(
192
+ context: RenderingContext,
193
+ instance: FieldInstance,
194
+ ): React.ReactNode {
195
+ let { data } = instance;
196
+ if (!data.viewText) return super.renderValue(context, instance, undefined);
197
+ return (
198
+ <span className={this.CSS.element(this.baseClass, "view-text")}>
199
+ {data.viewText}
200
+ </span>
201
+ );
202
+ }
203
+
204
+ formatValue(
205
+ context: RenderingContext,
206
+ instance: Instance,
207
+ ): React.ReactNode | string {
208
+ let { data } = instance;
209
+ return (
210
+ data.value && (data.text || this.renderChildren?.(context, instance))
211
+ );
212
+ }
213
+
214
+ handleClick(e: React.MouseEvent, instance: Instance): void {
215
+ if (this.native) e.stopPropagation();
216
+ else {
217
+ var el = document.getElementById(instance.data.id);
218
+ if (el) el.focus();
219
+ if (!instance.data.viewMode) {
220
+ e.preventDefault();
221
+ e.stopPropagation();
222
+ this.handleChange(e, instance, !instance.data.value);
186
223
  }
187
- }
188
-
189
- handleChange(
190
- e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent,
191
- instance: Instance,
192
- checked?: boolean,
193
- ): void {
194
- let { data } = instance;
195
-
196
- if (data.readOnly || data.disabled || data.viewMode) return;
197
-
198
- instance.set("value", checked != null ? checked : (e.target as HTMLInputElement).checked);
199
- }
224
+ }
225
+ }
226
+
227
+ handleChange(
228
+ e: React.ChangeEvent<HTMLInputElement> | React.MouseEvent,
229
+ instance: Instance,
230
+ checked?: boolean,
231
+ ): void {
232
+ let { data } = instance;
233
+
234
+ if (data.readOnly || data.disabled || data.viewMode) return;
235
+
236
+ instance.set(
237
+ "value",
238
+ checked != null ? checked : (e.target as HTMLInputElement).checked,
239
+ );
240
+ }
200
241
  }
201
242
 
202
243
  Checkbox.prototype.baseClass = "checkbox";
@@ -207,81 +248,93 @@ Checkbox.prototype.unfocusable = false;
207
248
  Widget.alias("checkbox", Checkbox);
208
249
 
209
250
  interface CheckboxCmpProps {
210
- key?: string;
211
- instance: FieldInstance<Checkbox>;
212
- data: Record<string, any>;
251
+ key?: string;
252
+ instance: FieldInstance<Checkbox>;
253
+ data: Record<string, any>;
213
254
  }
214
255
 
215
256
  interface CheckboxCmpState {
216
- value: unknown;
257
+ value: unknown;
217
258
  }
218
259
 
219
260
  class CheckboxCmp extends VDOM.Component<CheckboxCmpProps, CheckboxCmpState> {
220
- constructor(props: CheckboxCmpProps) {
221
- super(props);
222
- this.state = {
223
- value: props.data.value,
224
- };
225
- }
226
-
227
- UNSAFE_componentWillReceiveProps(props: CheckboxCmpProps) {
228
- this.setState({
229
- value: props.data.value,
230
- });
231
- }
232
-
233
- render(): React.ReactElement {
234
- let { instance, data } = this.props;
235
- let { widget } = instance;
236
- let { baseClass, CSS } = widget;
237
-
238
- let check: string | boolean = false;
239
-
240
- if (this.state.value == null && widget.indeterminate) check = "indeterminate";
241
- else if (this.state.value) check = "check";
242
-
243
- return (
244
- <span
245
- key="check"
246
- tabIndex={widget.unfocusable || data.disabled ? undefined : (data.tabIndex as number) || 0}
247
- className={CSS.element(baseClass, "input", {
248
- checked: check,
249
- })}
250
- style={CSS.parseStyle(data.inputStyle)}
251
- id={data.id}
252
- onClick={this.onClick.bind(this)}
253
- onKeyDown={this.onKeyDown.bind(this)}
254
- >
255
- {check == "check" && <CheckIcon className={CSS.element(baseClass, "input-check")} />}
256
- {check == "indeterminate" && <SquareIcon className={CSS.element(baseClass, "input-check")} />}
257
- </span>
258
- );
259
- }
260
-
261
- onClick(e: React.MouseEvent): void {
262
- let { instance, data } = this.props;
263
- let { widget } = instance;
264
- if (!data.disabled && !data.readOnly) {
265
- e.stopPropagation();
266
- e.preventDefault();
267
- this.setState({ value: !this.state.value });
268
- widget.handleChange(e, instance, !this.state.value);
269
- }
270
- }
271
-
272
- onKeyDown(e: React.KeyboardEvent): void {
273
- let { instance } = this.props;
274
- const { widget } = instance;
275
- if (
276
- widget.handleKeyDown &&
277
- widget.handleKeyDown(e as unknown as React.KeyboardEvent<Element>, instance) === false
278
- )
279
- return;
280
-
281
- switch (e.keyCode) {
282
- case KeyCode.space:
283
- this.onClick(e as unknown as React.MouseEvent);
284
- break;
285
- }
286
- }
261
+ constructor(props: CheckboxCmpProps) {
262
+ super(props);
263
+ this.state = {
264
+ value: props.data.value,
265
+ };
266
+ }
267
+
268
+ UNSAFE_componentWillReceiveProps(props: CheckboxCmpProps) {
269
+ this.setState({
270
+ value: props.data.value,
271
+ });
272
+ }
273
+
274
+ render(): React.ReactElement {
275
+ let { instance, data } = this.props;
276
+ let { widget } = instance;
277
+ let { baseClass, CSS } = widget;
278
+
279
+ let check: string | boolean = false;
280
+
281
+ if (this.state.value == null && widget.indeterminate)
282
+ check = "indeterminate";
283
+ else if (this.state.value) check = "check";
284
+
285
+ return (
286
+ <span
287
+ key="check"
288
+ tabIndex={
289
+ widget.unfocusable || data.disabled
290
+ ? undefined
291
+ : (data.tabIndex as number) || 0
292
+ }
293
+ className={CSS.element(baseClass, "input", {
294
+ checked: check,
295
+ })}
296
+ style={CSS.parseStyle(data.inputStyle)}
297
+ id={data.id}
298
+ onClick={this.onClick.bind(this)}
299
+ onKeyDown={this.onKeyDown.bind(this)}
300
+ >
301
+ {check == "check" && (
302
+ <CheckIcon className={CSS.element(baseClass, "input-check")} />
303
+ )}
304
+ {check == "indeterminate" && (
305
+ <SquareIcon className={CSS.element(baseClass, "input-check")} />
306
+ )}
307
+ </span>
308
+ );
309
+ }
310
+
311
+ onClick(e: React.MouseEvent): void {
312
+ let { instance, data } = this.props;
313
+ let { widget } = instance;
314
+ if (!data.disabled && !data.readOnly) {
315
+ e.stopPropagation();
316
+ e.preventDefault();
317
+ this.setState({ value: !this.state.value });
318
+ widget.handleChange(e, instance, !this.state.value);
319
+ }
320
+ }
321
+
322
+ onKeyDown(e: React.KeyboardEvent): void {
323
+ let { instance } = this.props;
324
+ const { widget } = instance;
325
+ if (
326
+ widget.handleKeyDown &&
327
+ widget.handleKeyDown(
328
+ e as unknown as React.KeyboardEvent<Element>,
329
+ instance,
330
+ ) === false
331
+ )
332
+ return;
333
+
334
+ switch (e.keyCode) {
335
+ case KeyCode.space:
336
+ this.onClick(e as unknown as React.MouseEvent);
337
+ break;
338
+ }
339
+ }
287
340
  }
@@ -111,6 +111,12 @@ export interface DateTimeFieldConfig extends FieldConfig {
111
111
  /** Additional configuration to be passed to the dropdown. */
112
112
  dropdownOptions?: Partial<DropdownConfig>;
113
113
 
114
+ /** Type of picker to show. Can be `calendar`, `time`, `list`, or `auto`. Default is `auto`. */
115
+ picker?: "calendar" | "time" | "list" | "auto";
116
+
117
+ /** Time step in minutes for the time picker. */
118
+ step?: number;
119
+
114
120
  /** Custom validation function. */
115
121
  onValidate?:
116
122
  | string
@@ -92,14 +92,14 @@ export interface TextFieldConfig extends FieldConfig {
92
92
  | string
93
93
  | ((e: KeyboardEvent, instance: Instance) => boolean | void);
94
94
 
95
- /** Custom validation function. */
95
+ /** Custom validation function. Can return a Promise for async validation. */
96
96
  onValidate?:
97
97
  | string
98
98
  | ((
99
99
  value: string,
100
100
  instance: Instance,
101
101
  validationParams: any
102
- ) => string | undefined | false);
102
+ ) => string | undefined | false | Promise<string | undefined | false>);
103
103
  }
104
104
 
105
105
  // Legacy alias for backward compatibility