@componyx/ui 0.0.0-stage → 1.0.3

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 (169) hide show
  1. package/AppSkin/AppSkin.css +1268 -0
  2. package/AppSkin/AppSkin.js +2748 -0
  3. package/AppSkin/Themes/Default.css +241 -0
  4. package/Base/Base.js +3407 -0
  5. package/Base/ComponentIcons.css +66 -0
  6. package/Base/Font/ComponentIcons.woff +0 -0
  7. package/Base/Font/UI.woff +0 -0
  8. package/Base/Library.js +8432 -0
  9. package/Base/NavigationManager.js +462 -0
  10. package/Base/ResponsiveTemplates.js +371 -0
  11. package/Base/Sanitizer.js +288 -0
  12. package/Base/Themes/Default.css +255 -0
  13. package/Base/UI.css +618 -0
  14. package/Base/UIResourcePath.js +6 -0
  15. package/Bindary/Bindary.js +2011 -0
  16. package/Bindary/Modules/Connection.js +216 -0
  17. package/Bindary/Modules/Core.js +854 -0
  18. package/Bindary/Modules/DataUpdater.js +351 -0
  19. package/Bindary/Modules/ExpressionEngine.js +347 -0
  20. package/Bindary/Modules/ProxyManager.js +482 -0
  21. package/Bindary/Modules/Renderer.js +605 -0
  22. package/Bindary/Modules/Router.js +291 -0
  23. package/Bindary/Modules/Scroller.js +89 -0
  24. package/Bindary/Modules/Template.js +1273 -0
  25. package/BookmarkSpy/BookmarkSpy.js +430 -0
  26. package/Box/Box.css +36 -0
  27. package/Box/Box.js +1685 -0
  28. package/Button/Button.css +470 -0
  29. package/Button/Button.js +1398 -0
  30. package/Button/Themes/Default.css +200 -0
  31. package/Carousel/Carousel.css +273 -0
  32. package/Carousel/Carousel.js +607 -0
  33. package/ColorButton/ColorButton.css +39 -0
  34. package/ColorButton/ColorButton.js +336 -0
  35. package/ColorPicker/ColorPicker.css +359 -0
  36. package/ColorPicker/ColorPicker.js +972 -0
  37. package/ComboBox/ComboBox.css +357 -0
  38. package/ComboBox/ComboBox.js +2342 -0
  39. package/ComboBox/Themes/Default.css +23 -0
  40. package/DataPager/DataPager.css +72 -0
  41. package/DataPager/DataPager.js +674 -0
  42. package/DatePicker/DatePicker.css +227 -0
  43. package/DatePicker/DatePicker.js +1531 -0
  44. package/DatePicker/Themes/Default.css +26 -0
  45. package/Dialog/Dialog.css +106 -0
  46. package/Dialog/Dialog.js +572 -0
  47. package/Dialog/Themes/Default.css +10 -0
  48. package/Editor/Data/Emoji.json +8285 -0
  49. package/Editor/Data/Special.json +1042 -0
  50. package/Editor/Editor.css +1562 -0
  51. package/Editor/Editor.js +4058 -0
  52. package/Editor/Font/Editor.woff +0 -0
  53. package/Editor/Modules/ComponentFactory.js +565 -0
  54. package/Editor/Modules/ContentManager.js +748 -0
  55. package/Editor/Modules/DialogManager.js +1234 -0
  56. package/Editor/Modules/EventManager.js +458 -0
  57. package/Editor/Modules/Format.js +950 -0
  58. package/Editor/Modules/History.js +191 -0
  59. package/Editor/Modules/LayoutState.js +379 -0
  60. package/Editor/Modules/ListManager.js +296 -0
  61. package/Editor/Modules/MenuManager.js +388 -0
  62. package/Editor/Modules/NodeManager.js +681 -0
  63. package/Editor/Modules/ParagraphButtons.js +122 -0
  64. package/Editor/Modules/Resizer.js +176 -0
  65. package/Editor/Modules/SelectionRange.js +564 -0
  66. package/Editor/Modules/SourceViewBuilder.js +212 -0
  67. package/Editor/Modules/SymbolPicker.js +208 -0
  68. package/Editor/Modules/Table.js +2327 -0
  69. package/Editor/Modules/TableDialog.js +757 -0
  70. package/Editor/Modules/Toolbar.js +375 -0
  71. package/Editor/Modules/TooltipMenu.js +125 -0
  72. package/Editor/Modules/Utility.js +131 -0
  73. package/Editor/Themes/Default.css +204 -0
  74. package/FileUpload/FileUpload.css +156 -0
  75. package/FileUpload/FileUpload.js +898 -0
  76. package/FileUpload/Themes/Default.css +17 -0
  77. package/Form/Form.css +1934 -0
  78. package/Form/Form.js +4943 -0
  79. package/Form/Modules/ActionManager.js +368 -0
  80. package/Form/Modules/BuildPanelManager.js +319 -0
  81. package/Form/Modules/ComponentFactory.js +468 -0
  82. package/Form/Modules/ComponentPanel.js +265 -0
  83. package/Form/Modules/ConfigPanelManager.js +685 -0
  84. package/Form/Modules/DataObserver.js +717 -0
  85. package/Form/Modules/Databinder.js +602 -0
  86. package/Form/Modules/Draggable.js +756 -0
  87. package/Form/Modules/OptionsPanel.js +342 -0
  88. package/Form/Modules/Renderer.js +1889 -0
  89. package/Form/Modules/RuleEngine.js +585 -0
  90. package/Form/Modules/RulesPanel.js +1158 -0
  91. package/Form/Modules/Types.js +1709 -0
  92. package/Form/Modules/ValidationManager.js +194 -0
  93. package/Form/Themes/Default.css +216 -0
  94. package/FormField/FormField.css +468 -0
  95. package/FormField/FormField.js +576 -0
  96. package/FormField/Themes/Default.css +99 -0
  97. package/Grid/Grid.css +544 -0
  98. package/Grid/Grid.js +3761 -0
  99. package/Grid/Themes/Default.css +43 -0
  100. package/LICENSE +126 -0
  101. package/MaskedTextBox/MaskedTextBox.css +28 -0
  102. package/MaskedTextBox/MaskedTextBox.js +642 -0
  103. package/MaskedTextBox/Themes/Default.css +6 -0
  104. package/Menu/Menu.css +328 -0
  105. package/Menu/Menu.js +2386 -0
  106. package/Menu/Themes/Default.css +24 -0
  107. package/NumericBox/NumericBox.css +120 -0
  108. package/NumericBox/NumericBox.js +984 -0
  109. package/PanelBar/PanelBar.css +123 -0
  110. package/PanelBar/PanelBar.js +505 -0
  111. package/PanelBar/Themes/Default.css +51 -0
  112. package/PieChart/PieChart.css +95 -0
  113. package/PieChart/PieChart.js +820 -0
  114. package/PieChart/Themes/Default.css +9 -0
  115. package/README.md +178 -3
  116. package/Slider/Slider.css +348 -0
  117. package/Slider/Slider.js +1306 -0
  118. package/Slider/Themes/Default.css +44 -0
  119. package/TabStrip/TabStrip.css +52 -0
  120. package/TabStrip/TabStrip.js +362 -0
  121. package/TabStrip/Themes/Default.css +35 -0
  122. package/TimePicker/Themes/Default.css +30 -0
  123. package/TimePicker/TimePicker.css +253 -0
  124. package/TimePicker/TimePicker.js +1485 -0
  125. package/TooltipManager/Themes/Default.css +21 -0
  126. package/TooltipManager/TooltipManager.css +227 -0
  127. package/TooltipManager/TooltipManager.js +791 -0
  128. package/Validator/Validator.css +54 -0
  129. package/Validator/Validator.js +2508 -0
  130. package/componyx.html-data.json +619 -0
  131. package/index.js +27 -0
  132. package/package.json +43 -4
  133. package/types/AppSkin.d.ts +842 -0
  134. package/types/Base.d.ts +1034 -0
  135. package/types/Bindary.d.ts +1196 -0
  136. package/types/BookmarkSpy.d.ts +112 -0
  137. package/types/Box.d.ts +374 -0
  138. package/types/Button.d.ts +455 -0
  139. package/types/Carousel.d.ts +136 -0
  140. package/types/ColorButton.d.ts +120 -0
  141. package/types/ColorPicker.d.ts +225 -0
  142. package/types/ComboBox.d.ts +507 -0
  143. package/types/DataPager.d.ts +152 -0
  144. package/types/DatePicker.d.ts +354 -0
  145. package/types/Dialog.d.ts +160 -0
  146. package/types/Editor.d.ts +1289 -0
  147. package/types/FileUpload.d.ts +206 -0
  148. package/types/Form.d.ts +3078 -0
  149. package/types/FormField.d.ts +204 -0
  150. package/types/Grid.d.ts +911 -0
  151. package/types/Library.d.ts +1899 -0
  152. package/types/MaskedTextBox.d.ts +91 -0
  153. package/types/Menu.d.ts +577 -0
  154. package/types/NumericBox.d.ts +310 -0
  155. package/types/PanelBar.d.ts +223 -0
  156. package/types/PieChart.d.ts +224 -0
  157. package/types/ResponsiveTemplates.d.ts +108 -0
  158. package/types/Slider.d.ts +227 -0
  159. package/types/TabStrip.d.ts +185 -0
  160. package/types/TimePicker.d.ts +265 -0
  161. package/types/TooltipManager.d.ts +178 -0
  162. package/types/UI.d.ts +29 -0
  163. package/types/Validator.d.ts +653 -0
  164. package/types/index.d.ts +59 -0
  165. package/ui.css +11783 -0
  166. package/ui.js +79477 -0
  167. package/ui.min.css +138 -0
  168. package/ui.min.js +264 -0
  169. package/ui.min.js.map +1 -0
@@ -0,0 +1,984 @@
1
+ /*! Componyx.UI | (c) E.H. Daanen / Componyx | BUSL-1.1 | componyx.com/license */
2
+ import '../Base/Base.js';
3
+ import '../Base/Library.js';
4
+ import '../Button/Button.js';
5
+
6
+ (function (window)
7
+ {
8
+ /**
9
+ * NumericBox class.
10
+ * @class
11
+ * @memberof componyx.UI
12
+ * @augments componyx.UI.base.Component
13
+ * @mixes componyx.UI.base.methods
14
+ * @param {String} id The id of the component.
15
+ * @param {Object|HTMLElement} properties The properties used to initialize the component or the container element.
16
+ * @returns {Object} An instance of the component.
17
+ */
18
+ componyx.UI.NumericBox = function NumericBox(id, properties)
19
+ {
20
+ // define private properties
21
+ var _instance = this,
22
+ _timerId = null,
23
+ _input,
24
+ _lastValue = '',
25
+ _lastLiveValue = '',
26
+ _pointerDown = false, _selectTextRangeTimerId;
27
+ $base.static.ThemeOption;
28
+ var _roundingOption = componyx.UI.NumericBox.RoundingOption,
29
+ _classOption =
30
+ {
31
+ DISABLED: 'disabled',
32
+ READONLY: 'read-only',
33
+ BUTTONS: 'buttons',
34
+ BUTTONHOLDER: 'button-holder',
35
+ BUTTON: 'button',
36
+ PLUS: 'plus',
37
+ MINUS: 'minus',
38
+ VERTICAL: 'vertical'
39
+ };
40
+
41
+ // define public properties
42
+ /**
43
+ * Gets or sets the css class of the numeric box when it is disabled.
44
+ * @type {String|null}
45
+ */
46
+ this.cssClassDisabled = null;
47
+
48
+ /**
49
+ * Gets or sets the css class of the numeric box when it is readonly.
50
+ * @type {String|null}
51
+ */
52
+ this.cssClassReadOnly = null;
53
+
54
+ /**
55
+ * Gets or sets the css class of the button holder.
56
+ * @type {String|null}
57
+ */
58
+ this.cssClassButtonHolder = null;
59
+
60
+ /**
61
+ * Gets or sets the css class of the buttons.
62
+ * @type {String|null}
63
+ */
64
+ this.cssClassButton = null;
65
+
66
+ /**
67
+ * Gets or sets the css class of the plus button.
68
+ * @type {String|null}
69
+ */
70
+ this.cssClassPlus = null;
71
+
72
+ /**
73
+ * Gets or sets the css class of the minus button.
74
+ * @type {String|null}
75
+ */
76
+ this.cssClassMinus = null;
77
+
78
+ /**
79
+ * Gets or sets if the numeric box is disabled.
80
+ * @type {Boolean}
81
+ */
82
+ this.disabled = false;
83
+
84
+ /**
85
+ * Gets or sets if the numeric box is readonly.
86
+ * @type {Boolean}
87
+ */
88
+ this.readOnly = false;
89
+
90
+ /**
91
+ * Gets or sets if keyboard navigation is allowed.
92
+ * @type {Boolean}
93
+ */
94
+ this.keyboardNavigation = true;
95
+
96
+ /**
97
+ * Gets or sets if the plus and minus buttons are visible.
98
+ * @type {Boolean}
99
+ */
100
+ this.showButtons = true;
101
+
102
+ /**
103
+ * Gets or sets a value indicating if the buttons are displayed vertically instead of horizontally.
104
+ * @type {Boolean}
105
+ */
106
+ this.verticalButtons = true;
107
+
108
+ /**
109
+ * Gets or sets a value indicating if the buttons are focusable.
110
+ * @type {Boolean}
111
+ */
112
+ this.focusableButtons = true;
113
+
114
+ /**
115
+ * Gets or sets the minimium allowed value.
116
+ * @type {Number|null}
117
+ */
118
+ this.minValue = null;
119
+
120
+ /**
121
+ * Gets or sets the maximum allowed value.
122
+ * @type {Number|null}
123
+ */
124
+ this.maxValue = null;
125
+
126
+ /**
127
+ * Gets or sets the width of the component in the specified CSS unit (e.g., px, %, or ch).
128
+ * @type {String}
129
+ */
130
+ this.width = '';
131
+
132
+ /**
133
+ * Gets or sets the incremental value when using plus or minus.
134
+ * @type {Number}
135
+ */
136
+ this.incrementalValue = 1;
137
+
138
+ /**
139
+ * Gets or sets the placeholder which is visible when the input box has no value.
140
+ * @type {String|null}
141
+ */
142
+ this.placeholder = null;
143
+
144
+ /**
145
+ * Gets or sets the decimal separator. Default: '.'.
146
+ * @type {String}
147
+ */
148
+ this.decimalSeparator = '.';
149
+
150
+ /**
151
+ * Gets or sets the group separator.
152
+ * @type {String|null}
153
+ */
154
+ this.groupSeparator = null;
155
+
156
+ /**
157
+ * Gets or sets the amount of decimal places.
158
+ * @type {Number}
159
+ */
160
+ this.precision = 0;
161
+
162
+ /**
163
+ * Gets or sets the decimal rounding type that should be applied.
164
+ * @type {componyx.UI.NumericBox.RoundingOption}
165
+ */
166
+ this.rounding = _roundingOption.ROUND;
167
+
168
+ /**
169
+ * Gets or sets if the input value can hold leading zeros.
170
+ * @type {Boolean}
171
+ */
172
+ this.leadingZeros = false;
173
+
174
+ /**
175
+ * Gets or sets if the input value can hold trailing zeros at the decimal side.
176
+ * @type {Boolean}
177
+ */
178
+ this.trailingZeros = true;
179
+
180
+ /**
181
+ * Gets or sets the value to right-align the digits by padding this value to the left.
182
+ * @type {String|null}
183
+ */
184
+ this.digitPadLeftValue = null;
185
+
186
+ /**
187
+ * Gets or sets if the input value is selected when the input gets focus.
188
+ * @type {Boolean}
189
+ */
190
+ this.selectOnFocus = false;
191
+
192
+ /**
193
+ * Gets or sets the id of the focus group to which this control belongs.
194
+ * @type {String|null}
195
+ */
196
+ this.focusGroupId = null;
197
+
198
+ /**
199
+ * Gets or sets the value which indicates whether this control should get focus when there is no control focused in the focus group.
200
+ * @type {Boolean}
201
+ */
202
+ this.focusGroupFirst = false;
203
+
204
+ /**
205
+ * Gets or sets the input field name of the control.
206
+ * @type {String}
207
+ */
208
+ this.name = '';
209
+
210
+ /**
211
+ * Gets or sets the initial value of the numeric box and holds the selected value on a postback.
212
+ * @type {Number|null}
213
+ */
214
+ this.value = null;
215
+
216
+ /**
217
+ * Gets or sets the id of the base button.
218
+ * @type {String|null}
219
+ */
220
+ this.buttonId = null;
221
+
222
+ /**
223
+ * Gets or sets the tooltip manager used to display tooltips.
224
+ * @type {String|null}
225
+ */
226
+ this.tooltipManagerId = null;
227
+
228
+ /**
229
+ * Gets or sets the id of the tooltip to show.
230
+ * @type {String|null}
231
+ */
232
+ this.tooltipId = null;
233
+
234
+ /**
235
+ * Gets or sets the clientid of the HTML input.
236
+ * @type {String|null}
237
+ */
238
+ this.inputId = null;
239
+
240
+
241
+ /**
242
+ * @class
243
+ * @augments componyx.UI.base.Events
244
+ * @memberof componyx.UI.NumericBox
245
+ * @property {componyx.UI.base.Event} onFocus - Event which fires when the component is focused.
246
+ * @property {componyx.UI.base.Event} onBlur - Event which fires when the component is blurred.
247
+ * @property {componyx.UI.base.Event} onInputFocus - Event which fires when the input is focused. @see {@link componyx.UI.NumericBox.InputEventArgs}
248
+ * @property {componyx.UI.base.Event} onInputBlur - Event which fires when the input is blurred. @see {@link componyx.UI.NumericBox.InputEventArgs}
249
+ * @property {componyx.UI.base.Event} onChange - Event which fires when the input changes. @see {@link componyx.UI.NumericBox.ChangeEventArgs}
250
+ * @property {componyx.UI.base.Event} onChanged - Event which fires when the input is changed (onblur or onpointerup). @see {@link componyx.UI.NumericBox.ChangeEventArgs}
251
+ * @property {componyx.UI.base.Event} onIncrement - Event which fires when the value is incremented. @see {@link componyx.UI.NumericBox.StepEventArgs}
252
+ * @property {componyx.UI.base.Event} onDecrement - Event which fires when the value is decremented. @see {@link componyx.UI.NumericBox.StepEventArgs}
253
+ * @see {@link componyx.UI.base.Events}
254
+ */
255
+ function NumericBoxEvents(events)
256
+ {
257
+ Object.assign(this, events);
258
+ this.onFocus = $base.static.createEvent('onFocus');
259
+ this.onBlur = $base.static.createEvent('onBlur');
260
+ this.onInputFocus = $base.static.createEvent('onInputFocus');
261
+ this.onInputBlur = $base.static.createEvent('onInputBlur');
262
+ this.onChange = $base.static.createEvent('onChange');
263
+ this.onChanged = $base.static.createEvent('onChanged');
264
+ this.onIncrement = $base.static.createEvent('onIncrement');
265
+ this.onDecrement = $base.static.createEvent('onDecrement');
266
+ }
267
+
268
+ /**
269
+ * NumericBox events
270
+ * @type {componyx.UI.NumericBox.NumericBoxEvents}
271
+ */
272
+ this.events = new NumericBoxEvents(this.events);
273
+
274
+ /**
275
+ * NumericBox input focus/blur event arguments.
276
+ * @typedef {Object} InputEventArgs
277
+ * @memberof componyx.UI.NumericBox
278
+ * @property {Event} event - The original event object.
279
+ */
280
+
281
+ /**
282
+ * NumericBox change event arguments.
283
+ * @typedef {Object} ChangeEventArgs
284
+ * @memberof componyx.UI.NumericBox
285
+ * @property {String} value - The input value without group separators and with '.' as decimal separator.
286
+ * @property {Event} event - The original event object.
287
+ * @property {Boolean} [incremental] - A value indicating if the change was caused by an increment or decrement (onChange only).
288
+ */
289
+
290
+ /**
291
+ * NumericBox increment/decrement event arguments.
292
+ * @typedef {Object} StepEventArgs
293
+ * @memberof componyx.UI.NumericBox
294
+ * @property {String} value - The new value without group separators and with '.' as decimal separator.
295
+ * @property {String} previousValue - The previous value without group separators and with '.' as decimal separator.
296
+ * @property {Event} event - The original event object.
297
+ */
298
+
299
+ // inherit base instance members
300
+ $base.Component.apply(this, [id, properties]);
301
+
302
+
303
+ /**
304
+ * Sets the placeholder text.
305
+ * @param {String} text The placeholder text.
306
+ */
307
+ this.setPlaceholder = function (text)
308
+ {
309
+ _input.placeholder = text;
310
+ _instance.placeholder = text;
311
+ };
312
+
313
+ /**
314
+ * Selects the text of the input box.
315
+ */
316
+ this.select = function ()
317
+ {
318
+ select();
319
+ };
320
+
321
+ /**
322
+ * Sets focus on the input element.
323
+ */
324
+ this.focus = function ()
325
+ {
326
+ _input.focus();
327
+ };
328
+
329
+ /**
330
+ * Gets the input element.
331
+ */
332
+ this.getInput = function ()
333
+ {
334
+ return _input;
335
+ };
336
+
337
+ /**
338
+ * Gets the input value.
339
+ * @returns {String} The value as formatted string.
340
+ */
341
+ this.getValue = function ()
342
+ {
343
+ return _input.value;
344
+ };
345
+
346
+ /**
347
+ * Gets the value.
348
+ * @returns {Number|null} The value as number.
349
+ */
350
+ this.getNumberValue = function ()
351
+ {
352
+ let value = getValue();
353
+
354
+ if ($lib.isEmpty(value))
355
+ return null;
356
+
357
+ const decimals = Math.max(value.lastIndexOf(','), value.lastIndexOf('.'));
358
+ if (decimals === -1)
359
+ return Number(value);
360
+
361
+ const groups = value.split(/[,\.]/);
362
+ const d = groups.at(-1).length;
363
+ const n = groups.join('');
364
+ return Number(n.slice(0, -d) + '.' + n.slice(-d));
365
+ };
366
+
367
+ /**
368
+ * Sets the input value.
369
+ * @param {String} value The value to set.
370
+ * @param {boolean} [fireChange=true] A value indicating if the change event is fired.
371
+ */
372
+ this.setValue = function (value, fireChange)
373
+ {
374
+ if ($lib.isEmpty(value))
375
+ value = '';
376
+
377
+ setValue(value);
378
+
379
+ if (fireChange !== false)
380
+ valueChanged(false, false, false);
381
+ else
382
+ _lastLiveValue = _lastValue = value;
383
+ };
384
+
385
+ /**
386
+ * Resets the input to the initial value.
387
+ * @param {boolean} [fireChange=true] A value indicating if the change event is fired.
388
+ */
389
+ this.reset = function (fireChange)
390
+ {
391
+ setValue(_instance.value);
392
+
393
+ if (fireChange !== false)
394
+ valueChanged(false, false, false);
395
+ else
396
+ _lastLiveValue = _lastValue = _instance.value;
397
+ };
398
+
399
+ /**
400
+ * Clears the input value.
401
+ * @param {boolean} [fireChange=true] A value indicating if the change event is fired.
402
+ */
403
+ this.clear = function (fireChange)
404
+ {
405
+ setValue('');
406
+
407
+ if (fireChange !== false)
408
+ valueChanged(false, false, false);
409
+ else
410
+ _lastLiveValue = _lastValue = '';
411
+ };
412
+
413
+ /**
414
+ * Increments the value with one step.
415
+ */
416
+ this.increment = function ()
417
+ {
418
+ increment(true);
419
+ };
420
+
421
+ /**
422
+ * Decrements the value with one step.
423
+ */
424
+ this.decrement = function ()
425
+ {
426
+ decrement(true);
427
+ };
428
+
429
+ /**
430
+ * Renders the component
431
+ */
432
+ this.render = function ()
433
+ {
434
+ if (_instance.renderState != $base.static.RenderState.RENDERING)
435
+ {
436
+ // call base render and return
437
+ $base.methods.render.call(_instance, preRender, 'numeric-box', false);
438
+ return;
439
+ }
440
+
441
+ // render logic after loading resources
442
+ draw();
443
+ };
444
+
445
+ /**
446
+ * Destroys the component.
447
+ * @see {@link componyx.UI.base.methods#destroy}
448
+ */
449
+ this.destroy = function (...args)
450
+ {
451
+ $base.methods.destroy.call(this, ...args);
452
+ dispose();
453
+ };
454
+
455
+ function preRender()
456
+ {
457
+ // initialize script and css
458
+ return ['NumericBox', ['Button']];
459
+ }
460
+
461
+ function draw()
462
+ {
463
+ let divButtonHolder = document.createElement('div'),
464
+ name = _instance.name, value;
465
+
466
+ _input = _instance.createSyncedInput(_instance.inputId, function ()
467
+ {
468
+ _instance.setValue(this.value);
469
+ }, false);
470
+
471
+
472
+ if (_instance.inputId)
473
+ {
474
+ if (_input.disabled)
475
+ _instance.disabled = true;
476
+
477
+ if (_input.readOnly)
478
+ _instance.readOnly = true;
479
+ }
480
+
481
+ value = _instance.value || _input.value;
482
+
483
+ if (!$lib.isEmpty(value))
484
+ setValue(value);
485
+
486
+ _input.className = _input.style.cssText = '';
487
+ _input.type = 'text';
488
+ _input.setAttribute('inputmode', 'numeric');
489
+ _input.setAttribute('pattern', '[0-9]*');
490
+ _input.readOnly = _instance.readOnly || false;
491
+ _input.disabled = _instance.disabled || false;
492
+ _input.placeholder = _instance.placeholder || '';
493
+
494
+ if (_instance.width)
495
+ _instance.element.style.width = $lib.unit(_instance.width);
496
+
497
+ if (name)
498
+ _input.setAttribute('name', name);
499
+
500
+ _input.setAttribute('autocomplete', 'off');
501
+ _instance.element.appendChild(_input);
502
+
503
+ if (_instance.disabled)
504
+ $lib.addClass(_instance.element, _instance.cssClassDisabled || _classOption.DISABLED);
505
+
506
+ if (_instance.readOnly)
507
+ $lib.addClass(_instance.element, _instance.cssClassReadOnly || _classOption.READONLY);
508
+
509
+ if (_instance.showButtons)
510
+ {
511
+ $lib.addClass(_instance.element, _classOption.BUTTONS);
512
+ createPlusButton(divButtonHolder);
513
+ createMinusButton(divButtonHolder);
514
+ divButtonHolder.className = _instance.cssClassButtonHolder || _classOption.BUTTONHOLDER;
515
+ _instance.element.appendChild(divButtonHolder);
516
+
517
+ if (_instance.verticalButtons)
518
+ $lib.addClass(divButtonHolder, _classOption.VERTICAL);
519
+ }
520
+
521
+ if (!$lib.isEmpty(_instance.focusGroupId))
522
+ {
523
+ if (!componyx.UI.NumericBox.FocusGroups[_instance.focusGroupId])
524
+ componyx.UI.NumericBox.FocusGroups[_instance.focusGroupId] = [];
525
+
526
+ componyx.UI.NumericBox.FocusGroups[_instance.focusGroupId].push(_instance);
527
+ }
528
+
529
+ if (_instance.tooltipManagerId && _instance.tooltipId)
530
+ {
531
+ $UI.store[_instance.tooltipManagerId].addTrigger(_input, _instance.tooltipId);
532
+ }
533
+
534
+ _lastValue = _lastLiveValue = _input.value;
535
+ bindEvents(_input);
536
+ $base.methods.postRender.call(_instance);
537
+ }
538
+
539
+ function createMinusButton(container)
540
+ {
541
+ var button = createButton(container, _instance.id + '_Min');
542
+ button.cssClass += ' ' + (_instance.cssClassMinus || _classOption.MINUS);
543
+
544
+ if (!_instance.disabled)
545
+ {
546
+ button.events.onPointerDown.priorityAdd(function (sender, args) { _pointerDown = true; holdDecrement(args.event); });
547
+ button.events.onClick.priorityAdd(function (sender, args)
548
+ {
549
+ // call decrement() when button has focus and the keyboard is used to fire the click event
550
+ if (!_pointerDown)
551
+ {
552
+ decrement();
553
+ valueChanged();
554
+ }
555
+
556
+
557
+ _pointerDown = false;
558
+ });
559
+ }
560
+ button.show();
561
+ }
562
+
563
+ function createPlusButton(container)
564
+ {
565
+ var button = createButton(container, _instance.id + '_Plus');
566
+ button.cssClass += ' ' + (_instance.cssClassPlus || _classOption.PLUS);
567
+
568
+ if (!_instance.disabled)
569
+ {
570
+ button.events.onPointerDown.priorityAdd(function (sender, args) { _pointerDown = true; holdIncrement(); });
571
+ button.events.onClick.priorityAdd(function (sender, args)
572
+ {
573
+ // call increment() when button has focus and the keyboard is used to fire the click event
574
+ if (!_pointerDown)
575
+ {
576
+ increment();
577
+ valueChanged();
578
+ }
579
+
580
+ _pointerDown = false;
581
+ });
582
+ }
583
+ button.show();
584
+ }
585
+
586
+ function createButton(container, id)
587
+ {
588
+ var button = $UI.createComponent(componyx.UI.Button, { id: id, containerElement: container });
589
+
590
+ button.transparentBorder = button.primary = false;
591
+ button.cssClass = _instance.cssClassButton || _classOption.BUTTON;
592
+ button.clone($UI.store[_instance.buttonId], _instance);
593
+ button.disabled = _instance.disabled;
594
+ button.delegateFocusEvents(_instance);
595
+
596
+ if (!_instance.focusableButtons)
597
+ button.tabIndex = -1;
598
+
599
+ return button;
600
+ }
601
+
602
+ function bindEvents(input)
603
+ {
604
+ if (!_instance.readOnly && !_instance.disabled)
605
+ {
606
+ $lib.on(input, 'keydown', validateInput);
607
+ $lib.on(input, 'input', acceptInput);
608
+
609
+ if (_instance.keyboardNavigation)
610
+ {
611
+ $lib.on(input, 'keydown', navigate);
612
+ $lib.on(input, 'keyup', checkValueChange);
613
+ }
614
+ }
615
+
616
+ $lib.on(input, 'blur', inputBlur);
617
+ $lib.on(document, 'pointerup', stopHold);
618
+ $lib.on(document, 'pointerdown', documentStop);
619
+
620
+ $lib.on(input, 'focus', function (e)
621
+ {
622
+ componyx.UI.NumericBox.FocusGroupActive[_instance.focusGroupId] = _instance;
623
+
624
+ if (!(_instance.readOnly || _instance.disabled) && _instance.selectOnFocus)
625
+ _selectTextRangeTimerId = setTimeout(function () { $lib.selectTextRange(input); }, 0);
626
+
627
+ _instance.events.onInputFocus.fire(_instance, { event: $lib.event });
628
+ });
629
+
630
+ $lib.on(input, 'focus', _instance.onFocus, _instance, _instance);
631
+ }
632
+ function validateInput()
633
+ {
634
+ var e = $lib.event,
635
+ keyCode = e.key,
636
+ sep = _instance.decimalSeparator,
637
+ sepKey = sep == keyCode,
638
+ value = _input.value;
639
+
640
+ if (keyCode == 'Enter')
641
+ {
642
+ inputBlur();
643
+ return;
644
+ }
645
+
646
+ if (' End Home ArrowLeft ArrowRight ArrowUp ArrowDown Delete Backspace Tab '.indexOf(' ' + keyCode + ' ') > -1)
647
+ return true;
648
+
649
+ if ((sepKey && (!_instance.precision || value.indexOf(sepKey) > -1)) || (!sepKey && keyCode.match(/[0-9]/) == null))
650
+ e.preventDefault();
651
+ }
652
+
653
+ function acceptInput()
654
+ {
655
+ let sep = _instance.decimalSeparator;
656
+
657
+ _input.__value = _input.value.replace(sep, '');
658
+ }
659
+
660
+ function checkValueChange()
661
+ {
662
+ valueChanged(true);
663
+ }
664
+
665
+ function navigate()
666
+ {
667
+ var e = $lib.event,
668
+ keyCode = e.key;
669
+
670
+ if (keyCode == 'ArrowUp')
671
+ increment();
672
+ else if (keyCode == 'ArrowDown')
673
+ decrement();
674
+ }
675
+
676
+ function valueChanged(live = false, incremental = false, fireHtmlEvent = true)
677
+ {
678
+ var e = $lib.event,
679
+ input = _input,
680
+ keyCode = (e) ? e.key : null;
681
+
682
+ if (keyCode == 'Tab')
683
+ return;
684
+
685
+ if (live && _lastLiveValue != input.value)
686
+ {
687
+ _lastLiveValue = input.value;
688
+ _instance.events.onChange.fire(_instance, { value: getValue(), event: $lib.event, incremental: incremental });
689
+ }
690
+ else if (!live && _lastValue != input.value)
691
+ {
692
+ _lastValue = _lastLiveValue = input.value;
693
+ _instance.events.onChanged.fire(_instance, { value: getValue(), event: $lib.event });
694
+
695
+ if (fireHtmlEvent)
696
+ $lib.fireEvent(input, 'change', true, true);
697
+ }
698
+ }
699
+
700
+ function inputBlur()
701
+ {
702
+ let value = getValue();
703
+
704
+ clearTimeout(_selectTextRangeTimerId);
705
+ setValue(value);
706
+ valueChanged(false, false);
707
+
708
+ _instance.events.onInputBlur.fire(_instance, { event: $lib.event });
709
+ _instance.onBlur.call(_instance);
710
+ }
711
+
712
+ function holdIncrement()
713
+ {
714
+ stopHold();
715
+ increment();
716
+ _timerId = setTimeout(function ()
717
+ {
718
+ _timerId = setInterval(function ()
719
+ {
720
+ if (_instance.renderState === $base.static.RenderState.RENDERED)
721
+ increment();
722
+ else
723
+ stopHold();
724
+ }, 50);
725
+ }, 500);
726
+ }
727
+
728
+ function increment(ignoreFocusBox)
729
+ {
730
+ if (!ignoreFocusBox)
731
+ {
732
+ let focusedBox = getFocusedBox();
733
+
734
+ if (focusedBox != null && focusedBox != _instance)
735
+ {
736
+ focusedBox.increment(); // decrement other numericBox in focus group
737
+ return;
738
+ }
739
+ }
740
+
741
+ let value = getValue(),
742
+ prevValue = value,
743
+ inc = _instance.incrementalValue,
744
+ min = _instance.minValue,
745
+ max = _instance.maxValue;
746
+
747
+ if ($lib.isEmpty(value))
748
+ {
749
+ if (isNumber(min))
750
+ value = min;
751
+ else if (isNumber(inc))
752
+ {
753
+ if (!isNumber(max) || inc <= max)
754
+ value = inc;
755
+ else
756
+ value = max;
757
+ }
758
+ else if (isNumber(max))
759
+ value = max;
760
+ else
761
+ value = 0;
762
+ }
763
+ else if (isNumber(value))
764
+ value = parseFloat(value) + inc;
765
+
766
+ setValue(value, true);
767
+ _instance.events.onIncrement.fire(_instance, { value: getValue(), previousValue: prevValue, event: $lib.event });
768
+ valueChanged(true, true);
769
+ }
770
+
771
+ function holdDecrement()
772
+ {
773
+ stopHold();
774
+ decrement();
775
+
776
+ _timerId = setTimeout(function ()
777
+ {
778
+ _timerId = setInterval(function ()
779
+ {
780
+ if (_instance.renderState === $base.static.RenderState.RENDERED)
781
+ decrement();
782
+ else
783
+ stopHold();
784
+ }, 50);
785
+ }, 500);
786
+ }
787
+
788
+ function decrement(ignoreFocusBox)
789
+ {
790
+ if (!ignoreFocusBox)
791
+ {
792
+ let focusedBox = getFocusedBox();
793
+
794
+ if (focusedBox != null && focusedBox != _instance)
795
+ {
796
+ focusedBox.decrement(); // decrement other numericBox in focus group
797
+ return;
798
+ }
799
+ }
800
+
801
+ let value = getValue(),
802
+ prevValue = value,
803
+ inc = _instance.incrementalValue,
804
+ min = _instance.minValue,
805
+ max = _instance.maxValue;
806
+
807
+ if ($lib.isEmpty(value))
808
+ {
809
+ if (isNumber(max))
810
+ value = max;
811
+ else if (isNumber(inc))
812
+ {
813
+ if (!isNumber(min) || inc >= min)
814
+ value = inc;
815
+ else
816
+ value = min;
817
+ }
818
+ else if (isNumber(min))
819
+ value = min;
820
+ else
821
+ value = 0;
822
+ }
823
+ else if (isNumber(value))
824
+ {
825
+ value = parseFloat(value) - inc;
826
+ }
827
+
828
+ setValue(value, true);
829
+ _instance.events.onDecrement.fire(_instance, { value: getValue(), previousValue: prevValue, event: $lib.event });
830
+ valueChanged(true, true);
831
+ }
832
+
833
+ function documentStop()
834
+ {
835
+ if (!_pointerDown)
836
+ stopHold();
837
+ }
838
+
839
+ function stopHold()
840
+ {
841
+ if (_timerId && _instance.renderState === $base.static.RenderState.RENDERED)
842
+ {
843
+ var focusedBox = getFocusedBox();
844
+
845
+ if (focusedBox?.element?.isConnected)
846
+ focusedBox.focus();
847
+ else if (_input?.element?.isConnected)
848
+ _input.focus();
849
+
850
+ valueChanged();
851
+ }
852
+
853
+ clearInterval(_timerId);
854
+ clearTimeout(_timerId);
855
+ _timerId = null;
856
+ }
857
+
858
+ function getFocusedBox()
859
+ {
860
+ if ($lib.isEmpty(_instance.focusGroupId))
861
+ return null;
862
+
863
+ var active = componyx.UI.NumericBox.FocusGroupActive[_instance.focusGroupId];
864
+
865
+ if (active)
866
+ return active;
867
+ else
868
+ return getFocusGroupFirst();
869
+ }
870
+
871
+ function getFocusGroupFirst()
872
+ {
873
+ var groups = componyx.UI.NumericBox.FocusGroups[_instance.focusGroupId],
874
+ index = $lib.indexOf(groups, function (item) { return item.focusGroupFirst });
875
+
876
+ if (index > -1)
877
+ return groups[index];
878
+ else
879
+ return groups[0];
880
+ }
881
+
882
+ function getValue()
883
+ {
884
+ let value = _input.value,
885
+ groupSep = _instance.groupSeparator;
886
+
887
+ if (groupSep)
888
+ {
889
+ groupSep = $lib.escapeRegExp(groupSep);
890
+ value = value.replace(new RegExp(groupSep, 'g'), '');
891
+ }
892
+
893
+ return value.replace(_instance.decimalSeparator, '.');
894
+ }
895
+
896
+ function isNumber(value)
897
+ {
898
+ return (!$lib.isEmpty(value) && !isNaN(value));
899
+ }
900
+
901
+ function formatNumber(value)
902
+ {
903
+ return $lib.formatNumber(value, _instance.leadingZeros, _instance.trailingZeros, _instance.precision, _roundingOption.getName(_instance.rounding), _instance.decimalSeparator, _instance.groupSeparator, _instance.digitPadLeftValue);
904
+ }
905
+
906
+ function setValue(value, incremental)
907
+ {
908
+ var min = _instance.minValue,
909
+ max = _instance.maxValue,
910
+ inc = _instance.incrementalValue;
911
+
912
+ if (isNumber(value))
913
+ {
914
+ if (inc > 1)
915
+ value = Math.round(value / inc) * inc; // Snap to nearest increment if requested
916
+
917
+ if (min != null && value < min)
918
+ value = (incremental && max != null) ? max : min;
919
+ else if (max != null && value > max)
920
+ value = (incremental && min != null) ? min : max;
921
+
922
+ value = formatNumber(value);
923
+ }
924
+
925
+ if (_input.value != value)
926
+ _input.__setValue(value);
927
+ }
928
+
929
+ function select()
930
+ {
931
+ var input = _input;
932
+ input.select();
933
+ }
934
+
935
+ function dispose()
936
+ {
937
+ var groups = componyx.UI.NumericBox.FocusGroups[_instance.focusGroupId] || null,
938
+ active = componyx.UI.NumericBox.FocusGroupActive,
939
+ index = -1;
940
+
941
+ if (!$lib.isEmpty(_instance.focusGroupId))
942
+ {
943
+ if (active[_instance.focusGroupId] === _instance)
944
+ delete active[_instance.focusGroupId];
945
+
946
+ if (groups)
947
+ index = $lib.indexOf(groups, function (item) { return (item === _instance) });
948
+
949
+ if (index > -1)
950
+ groups.splice(index, 1);
951
+ }
952
+
953
+ $lib.off(document, 'pointerup', stopHold);
954
+ $lib.off(document, 'pointerdown', documentStop);
955
+ }
956
+ };
957
+
958
+ /**
959
+ * @see {@link componyx.UI.base.methods}
960
+ */
961
+ componyx.UI.NumericBox.prototype = Object.create($base.methods);
962
+ componyx.UI.NumericBox.prototype.constructor = componyx.UI.NumericBox;
963
+ componyx.UI.NumericBox.FocusGroups = {};
964
+ componyx.UI.NumericBox.FocusGroupActive = {};
965
+
966
+ /**
967
+ * RoundingOption
968
+ * @readonly
969
+ * @enum {number}
970
+ */
971
+ componyx.UI.NumericBox.RoundingOption =
972
+ {
973
+ NONE: 0,
974
+ ROUND: 1,
975
+ FLOOR: 2,
976
+ CEIL: 3,
977
+
978
+ getName: function (value) { return $base.static.getKeyByValue(this, value).toLowerCase(); }
979
+ };
980
+ })();
981
+
982
+ const NumericBox = componyx.UI.NumericBox;
983
+
984
+ export { NumericBox };