@descope/web-components-ui 1.0.378 → 1.0.379

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 (94) hide show
  1. package/dist/cjs/index.cjs.js +3166 -1257
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.esm.js +4738 -2826
  5. package/dist/index.esm.js.map +1 -1
  6. package/dist/umd/1224.js +1 -1
  7. package/dist/umd/1438.js +3 -3
  8. package/dist/umd/1612.js +1 -1
  9. package/dist/umd/2773.js +4 -4
  10. package/dist/umd/3830.js +1 -1
  11. package/dist/umd/3951.js +1 -1
  12. package/dist/umd/3966.js +319 -0
  13. package/dist/umd/4024.js +1 -1
  14. package/dist/umd/4052.js +1 -1
  15. package/dist/umd/4392.js +1 -1
  16. package/dist/umd/4525.js +1 -1
  17. package/dist/umd/4978.js +1 -1
  18. package/dist/umd/5135.js +2 -2
  19. package/dist/umd/5517.js +1 -1
  20. package/dist/umd/5778.js +275 -0
  21. package/dist/umd/5806.js +1 -1
  22. package/dist/umd/5977.js +140 -0
  23. package/dist/umd/5977.js.LICENSE.txt +29 -0
  24. package/dist/umd/63.js +4 -4
  25. package/dist/umd/6770.js +1 -1
  26. package/dist/umd/7056.js +3 -3
  27. package/dist/umd/7284.js +1 -1
  28. package/dist/umd/7541.js +449 -0
  29. package/dist/umd/7541.js.LICENSE.txt +17 -0
  30. package/dist/umd/7911.js +2 -2
  31. package/dist/umd/{4028.js → 8060.js} +3 -3
  32. package/dist/umd/8137.js +1 -1
  33. package/dist/umd/8191.js +2 -2
  34. package/dist/umd/8655.js +123 -0
  35. package/dist/umd/9314.js +2 -2
  36. package/dist/umd/9423.js +6 -6
  37. package/dist/umd/9562.js +1 -1
  38. package/dist/umd/DescopeDev.js +1 -1
  39. package/dist/umd/descope-apps-list-index-js.js +1 -1
  40. package/dist/umd/descope-avatar-index-js.js +1 -1
  41. package/dist/umd/descope-button-index-js.js +1 -1
  42. package/dist/umd/descope-combo-box-index-js.js +5 -5
  43. package/dist/umd/descope-date-field-descope-calendar-index-js.js +1 -0
  44. package/dist/umd/descope-date-field-index-js.js +1 -0
  45. package/dist/umd/descope-email-field-index-js.js +1 -1
  46. package/dist/umd/descope-grid-descope-grid-custom-column-index-js.js +2 -2
  47. package/dist/umd/descope-grid-descope-grid-item-details-column-index-js.js +2 -2
  48. package/dist/umd/descope-grid-descope-grid-selection-column-index-js.js +1 -1
  49. package/dist/umd/descope-grid-descope-grid-text-column-index-js.js +4 -4
  50. package/dist/umd/descope-new-password-index-js.js +1 -1
  51. package/dist/umd/descope-number-field-index-js.js +1 -1
  52. package/dist/umd/descope-passcode-index-js.js +1 -1
  53. package/dist/umd/descope-radio-group-index-js.js +1 -1
  54. package/dist/umd/descope-text-field-index-js.js +1 -1
  55. package/dist/umd/index.js +1 -1
  56. package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +1 -1
  57. package/dist/umd/phone-fields-descope-phone-field-descope-phone-field-internal-index-js.js +1 -1
  58. package/dist/umd/phone-fields-descope-phone-field-index-js.js +1 -1
  59. package/dist/umd/phone-fields-descope-phone-input-box-field-descope-phone-input-box-internal-index-js.js +1 -1
  60. package/dist/umd/phone-fields-descope-phone-input-box-field-index-js.js +1 -1
  61. package/package.json +11 -5
  62. package/src/components/descope-combo-box/ComboBoxClass.js +7 -1
  63. package/src/components/descope-date-field/DateCounterClass.js +83 -0
  64. package/src/components/descope-date-field/DateFieldClass.js +675 -0
  65. package/src/components/descope-date-field/consts.js +55 -0
  66. package/src/components/descope-date-field/descope-calendar/CalendarClass.js +666 -0
  67. package/src/components/descope-date-field/descope-calendar/helpers.js +186 -0
  68. package/src/components/descope-date-field/descope-calendar/index.js +9 -0
  69. package/src/components/descope-date-field/formats.js +49 -0
  70. package/src/components/descope-date-field/helpers.js +72 -0
  71. package/src/components/descope-date-field/icons.js +14 -0
  72. package/src/components/descope-date-field/index.js +10 -0
  73. package/src/components/descope-text-field/textFieldMappings.js +2 -0
  74. package/src/index.cjs.js +2 -0
  75. package/src/index.d.ts +2 -0
  76. package/src/index.js +2 -1
  77. package/src/mixins/inputValidationMixin.js +8 -2
  78. package/src/mixins/portalMixin.js +6 -3
  79. package/src/theme/components/calendar.js +94 -0
  80. package/src/theme/components/dateField.js +63 -0
  81. package/src/theme/components/index.js +4 -0
  82. package/src/theme/components/inputWrapper.js +6 -0
  83. package/src/theme/components/textField.js +1 -0
  84. package/dist/umd/4746.js +0 -124
  85. package/dist/umd/7531.js +0 -319
  86. package/dist/umd/8866.js +0 -275
  87. package/dist/umd/9092.js +0 -1086
  88. package/dist/umd/9092.js.LICENSE.txt +0 -27
  89. package/dist/umd/descope-date-picker-index-js.js +0 -1
  90. package/src/components/descope-date-picker/index.js +0 -20
  91. /package/dist/umd/{7531.js.LICENSE.txt → 3966.js.LICENSE.txt} +0 -0
  92. /package/dist/umd/{8866.js.LICENSE.txt → 5778.js.LICENSE.txt} +0 -0
  93. /package/dist/umd/{4028.js.LICENSE.txt → 8060.js.LICENSE.txt} +0 -0
  94. /package/dist/umd/{4746.js.LICENSE.txt → 8655.js.LICENSE.txt} +0 -0
@@ -0,0 +1,675 @@
1
+ import { createBaseInputClass } from '../../baseClasses/createBaseInputClass';
2
+ import {
3
+ createStyleMixin,
4
+ draggableMixin,
5
+ componentNameValidationMixin,
6
+ portalMixin,
7
+ } from '../../mixins';
8
+ import { forwardAttrs, getComponentName } from '../../helpers/componentHelpers';
9
+ import { compose } from '../../helpers';
10
+ import {
11
+ newDate,
12
+ isValidTimestamp,
13
+ formatTimestamp,
14
+ isSupportedKey,
15
+ isNumber,
16
+ getKeyMap,
17
+ getCurrentTime,
18
+ overrideConstructedStylesheet,
19
+ } from './helpers';
20
+ import { formats } from './formats';
21
+ import { calendarIcon } from './icons';
22
+ import { counterConfig, DEFAULT_FORMAT, DIVIDER, NATIVE_FORMAT } from './consts';
23
+ import { DateCounter } from './DateCounterClass';
24
+
25
+ export const componentName = getComponentName('date-field');
26
+
27
+ // we set baseSelector to `vaadin-popover` as a temporary hack, so our portalMixin will
28
+ // be able to process this component's overlay. The whole process needs refactoring as soon as possible.
29
+ const BASE_SELECTOR = 'vaadin-popover';
30
+ const BaseInputClass = createBaseInputClass({ componentName, baseSelector: BASE_SELECTOR });
31
+
32
+ const dateFieldAttrs = ['format', 'opened', 'initial-value'];
33
+ const calendarAttrs = ['years-range', 'calendar-months', 'calendar-weekdays'];
34
+ const observedAttrs = [...dateFieldAttrs, ...calendarAttrs];
35
+
36
+ class RawDateFieldClass extends BaseInputClass {
37
+ timestamp = '';
38
+
39
+ format = DEFAULT_FORMAT;
40
+
41
+ selectedCounterIdx = 0;
42
+
43
+ dateCounters = [
44
+ new DateCounter(counterConfig.MONTH),
45
+ new DateCounter(counterConfig.DAY),
46
+ new DateCounter(counterConfig.YEAR),
47
+ ];
48
+
49
+ static get observedAttributes() {
50
+ return [].concat(BaseInputClass.observedAttributes || [], observedAttrs);
51
+ }
52
+
53
+ constructor() {
54
+ super();
55
+
56
+ this.attachShadow({ mode: 'open' }).innerHTML = `
57
+ <style>
58
+ :host {
59
+ display: inline-block;
60
+ box-sizing: border-box;
61
+ user-select: none;
62
+ max-width: 100%;
63
+ }
64
+
65
+ :host ::slotted {
66
+ padding: 0;
67
+ }
68
+
69
+ .toggle-calendar {
70
+ cursor: pointer;
71
+ display: flex;
72
+ align-self: center;
73
+ z-index: 1;
74
+ }
75
+
76
+ descope-text-field .overlay-position-anchor {
77
+ position: absolute;
78
+ height: 100%;
79
+ width: 0;
80
+ z-index: 1;
81
+ pointer-events: none;
82
+ }
83
+ </style>
84
+ <div>
85
+ <descope-text-field>
86
+ <span slot="prefix" class="overlay-position-anchor"></span>
87
+ <span slot="suffix" class="toggle-calendar">
88
+ <descope-icon>${calendarIcon}</descope-icon>
89
+ </span>
90
+ </descope-text-field>
91
+ <vaadin-popover></vaadin-popover>
92
+ </div>
93
+ `;
94
+
95
+ this.inputElement = this.shadowRoot.querySelector('descope-text-field');
96
+ this.popoverToggleButton = this.inputElement.querySelector('.toggle-calendar');
97
+ this.overlayPositionAnchor = this.inputElement.querySelector('.overlay-position-anchor');
98
+
99
+ this.oninvalid = () => {
100
+ this.inputElement.setAttribute('invalid', 'true');
101
+ this.inputElement.focus();
102
+ };
103
+ }
104
+
105
+ get opened() {
106
+ return this.getAttribute('opened') === 'true';
107
+ }
108
+
109
+ // returns the input's value as a timestamp
110
+ get inputValueTimestamp() {
111
+ const date = formats[this.format].getDate(this.inputElement.value);
112
+
113
+ if (!isValidTimestamp(date?.getTime())) {
114
+ return null;
115
+ }
116
+
117
+ return date.getTime();
118
+ }
119
+
120
+ get sortedCounters() {
121
+ return this.format
122
+ .split(DIVIDER)
123
+ .map((placeholder) => this.dateCounters.find((dc) => dc.placeholder === placeholder));
124
+ }
125
+
126
+ get activeCounter() {
127
+ return this.sortedCounters[this.selectedCounterIdx];
128
+ }
129
+
130
+ get countersValue() {
131
+ return this.sortedCounters.map((dc) => dc.stringValue).join(DIVIDER);
132
+ }
133
+
134
+ get overlay() {
135
+ return this.baseElement.shadowRoot?.querySelector('vaadin-popover-overlay');
136
+ }
137
+
138
+ get backdrop() {
139
+ return this.overlay.shadowRoot?.querySelector('#backdrop');
140
+ }
141
+
142
+ get calendar() {
143
+ return this.overlay?.querySelector('descope-calendar');
144
+ }
145
+
146
+ get value() {
147
+ return this.timestamp;
148
+ }
149
+
150
+ set value(val) {
151
+ if (!val) return;
152
+
153
+ const numVal = Number(val);
154
+ const isValTimestamp = !Number.isNaN(numVal);
155
+
156
+ let date;
157
+ let timestamp;
158
+
159
+ if (isValTimestamp) {
160
+ date = newDate(numVal);
161
+ timestamp = numVal;
162
+ } else {
163
+ date = newDate(val);
164
+ timestamp = date.getTime();
165
+ }
166
+
167
+ if (!isValidTimestamp(timestamp) || timestamp === this.timestamp) {
168
+ return;
169
+ }
170
+
171
+ this.timestamp = timestamp;
172
+
173
+ this.updateInputDisplay();
174
+ this.updateDateCounters(date);
175
+
176
+ // since baseElement is set to vaadin-popover, we need to manually dispatch an input event to trigger getValidity
177
+ this.dispatchEvent(new Event('input'));
178
+ }
179
+
180
+ updateInputDisplay() {
181
+ this.inputElement.value = formatTimestamp(newDate(this.value).getTime(), this.format);
182
+ }
183
+
184
+ init() {
185
+ super.init?.();
186
+
187
+ this.updateFormatPattern();
188
+ this.initPopover();
189
+ this.initInputElement();
190
+
191
+ setTimeout(() => {
192
+ this.#overrideOverlaySettings();
193
+ }, 0);
194
+ }
195
+
196
+ initInputElement() {
197
+ this.popoverToggleButton.addEventListener('click', this.onPopoverToggle.bind(this));
198
+
199
+ this.inputElement.addEventListener('focus', this.onFocus.bind(this));
200
+ this.inputElement.addEventListener('blur', this.onBlur.bind(this));
201
+ this.inputElement.addEventListener('input', this.onInput.bind(this));
202
+ this.inputElement.addEventListener('click', this.handleMouseCaretPositionChange.bind(this));
203
+ this.inputElement.addEventListener('keydown', this.handleKeyDownValueChange.bind(this));
204
+ this.inputElement.addEventListener('keydown', this.handleKeydownCaretPositionChange.bind(this));
205
+ this.inputElement.addEventListener('keydown', this.handleValueChange.bind(this));
206
+
207
+ forwardAttrs(this, this.inputElement, {
208
+ includeAttrs: [
209
+ 'label',
210
+ 'label-type',
211
+ 'placeholder',
212
+ 'disabled',
213
+ 'readonly',
214
+ 'bordered',
215
+ 'required',
216
+ 'full-width',
217
+ 'st-host-direction',
218
+ 'pattern',
219
+ 'invalid',
220
+ 'bordered',
221
+ ],
222
+ });
223
+ }
224
+
225
+ initPopover() {
226
+ this.baseElement.target = this.overlayPositionAnchor;
227
+ this.baseElement.trigger = ['click'];
228
+ this.baseElement.withBackdrop = true;
229
+ this.baseElement.noCloseOnOutsideClick = true;
230
+ this.baseElement.renderer = this.#popoverRenderer.bind(this);
231
+
232
+ // override vaadin's constructed stylesheet which hides the host element
233
+ overrideConstructedStylesheet(this.baseElement);
234
+
235
+ // block popover events from focusing/blurring the text-field
236
+ this.baseElement.addEventListener('click', (e) => {
237
+ e.preventDefault();
238
+ e.stopPropagation();
239
+ });
240
+ }
241
+
242
+ #popoverRenderer(root) {
243
+ // popoverRenderer should run only once, when the popover is first rendering.
244
+ if (!root.firstChild) {
245
+ root.appendChild(this.#getPopoverContent());
246
+
247
+ // To prevent position flickering of the dialog we set opacity to 0
248
+ root.style.setProperty('opacity', '0');
249
+
250
+ setTimeout(() => {
251
+ // on first render we adjust the a anchor element in the input
252
+ // so vaadin computes the popover position according to the anchor position
253
+ // (otherwise it will simply center the popover below the input).
254
+ this.#adjustOverlayPosition();
255
+
256
+ // remove opacity to show overlay
257
+ root.style.setProperty('opacity', '1');
258
+
259
+ // on outside click - close popover. this event runs once on popover first render
260
+ // and does not need to be cleared
261
+ this.backdrop.addEventListener('click', this.closePopover.bind(this));
262
+ });
263
+ }
264
+
265
+ this.updateCalendarView();
266
+ }
267
+
268
+ #getPopoverContent() {
269
+ const ele = document.createElement('span');
270
+
271
+ ele.innerHTML = `<descope-calendar></descope-calendar>`;
272
+
273
+ const calendar = ele.querySelector('descope-calendar');
274
+
275
+ calendar.addEventListener('date-submit', this.onCalendarSubmit.bind(this));
276
+ calendar.addEventListener('cancel', this.closePopover.bind(this));
277
+
278
+ return ele;
279
+ }
280
+
281
+ #adjustOverlayPosition() {
282
+ const { width: inputEleWidth } = this.inputElement.getClientRects()[0];
283
+ const { width: calendarEleWidth } = this.calendar.getClientRects()[0];
284
+ const pos = inputEleWidth - calendarEleWidth / 2;
285
+ /* eslint-disable no-use-before-define */
286
+ this.overlayPositionAnchor.style.setProperty(
287
+ DateFieldClass.cssVarList.overlayAnchorPos,
288
+ `${pos}px`
289
+ );
290
+ }
291
+
292
+ // the default vaadin behavior is to attach the overlay to the body when opened
293
+ // we do not want that because it's difficult to style the overlay in this way
294
+ // so we override it to open inside the shadow DOM
295
+ #overrideOverlaySettings() {
296
+ this.overlay._attachOverlay = () => this.overlay.bringToFront();
297
+ this.overlay._detachOverlay = () => {};
298
+ this.overlay._enterModalState = () => {};
299
+ }
300
+
301
+ onPopoverToggle() {
302
+ this.opened ? this.closePopover() : this.openPopover();
303
+ }
304
+
305
+ openPopover() {
306
+ this.setAttribute('opened', 'true');
307
+ }
308
+
309
+ closePopover() {
310
+ this.removeAttribute('opened');
311
+ this.inputElement.focus();
312
+ }
313
+
314
+ getCounterById(id) {
315
+ return this.dateCounters.find((dc) => dc.id === id);
316
+ }
317
+
318
+ onCalendarSubmit() {
319
+ if (!this.isReadOnly) {
320
+ if (!this.calendar.value) return;
321
+
322
+ const calendarDate = newDate(this.calendar.value);
323
+
324
+ this.value = calendarDate.getTime();
325
+
326
+ this.getCounterById('year').replaceValue(calendarDate.getFullYear());
327
+ this.getCounterById('month').replaceValue(calendarDate.getMonth() + 1);
328
+ this.getCounterById('day').replaceValue(calendarDate.getDate());
329
+
330
+ this.dispatchEvent(new Event('input'));
331
+ }
332
+
333
+ this.closePopover();
334
+ }
335
+
336
+ updateCalendarView() {
337
+ const validInputVal =
338
+ isValidTimestamp(newDate(this.inputElement.value || '').getTime()) &&
339
+ formats[this.format].validate(this.inputElement.value);
340
+
341
+ if (this.inputValueTimestamp || validInputVal) {
342
+ this.calendar.setAttribute(
343
+ 'initial-value',
344
+ formatTimestamp(this.inputValueTimestamp || this.timestamp, NATIVE_FORMAT)
345
+ );
346
+ } else {
347
+ this.calendar.clearValue();
348
+ this.calendar.setAttribute('preview', formatTimestamp(getCurrentTime(), NATIVE_FORMAT));
349
+ }
350
+
351
+ forwardAttrs(this, this.calendar, {
352
+ includeAttrs: [
353
+ 'st-host-direction',
354
+ 'readonly',
355
+ 'initial-month',
356
+ 'initial-year',
357
+ 'years-range',
358
+ 'calendar-label-submit',
359
+ 'calendar-label-cancel',
360
+ 'calendar-months',
361
+ 'calendar-weekdays',
362
+ 'calendar-weekdays-short',
363
+ ],
364
+ });
365
+ }
366
+
367
+ onInput(e) {
368
+ if (!e.target.value) {
369
+ this.calendar?.clear();
370
+ this.calendar?.renderCalendar();
371
+ }
372
+ }
373
+
374
+ onFocus() {
375
+ if (!this.inputElement.value) {
376
+ this.inputElement.value = this.format;
377
+ this.setInputSelectionRange();
378
+ }
379
+ }
380
+
381
+ clearInputValue() {
382
+ this.inputElement.value = '';
383
+ this.resetDateCounters();
384
+ }
385
+
386
+ onBlur() {
387
+ if (this.inputValueTimestamp) {
388
+ this.value = this.inputValueTimestamp;
389
+ } else if (!this.opened && this.countersValue === this.format) {
390
+ this.clearInputValue();
391
+ }
392
+ }
393
+
394
+ onFormatUpdate(format) {
395
+ if (Object.keys(formats).includes(format)) {
396
+ this.format = format;
397
+ this.updateFormatPattern();
398
+ }
399
+ }
400
+
401
+ updateFormatPattern() {
402
+ const format = this.getAttribute('format') || this.format || DEFAULT_FORMAT;
403
+ this.setAttribute('type', 'date');
404
+ this.setAttribute('pattern', formats[format].pattern);
405
+ }
406
+
407
+ handleValueChange(e) {
408
+ if (isNumber(e.key)) {
409
+ e.preventDefault();
410
+
411
+ this.handleCountersValue(e.key);
412
+
413
+ if (this.activeCounter.isFull) {
414
+ this.selectNextCounter();
415
+ }
416
+
417
+ this.setInputSelectionRange();
418
+ }
419
+ }
420
+
421
+ getCounterIdx(caretPos) {
422
+ const [counter1ln, counter2ln] = this.sortedCounters.map((dc) => dc.length);
423
+
424
+ const c1 = caretPos <= counter1ln;
425
+ const c2 = caretPos >= counter1ln && caretPos <= counter1ln + counter2ln + 1;
426
+ const c3 = caretPos >= counter1ln + counter2ln + 2;
427
+
428
+ return [c1, c2, c3].indexOf(true);
429
+ }
430
+
431
+ handleCountersValue(val) {
432
+ this.activeCounter.add(val);
433
+ this.inputElement.value = this.countersValue;
434
+ }
435
+
436
+ setSelectedCounterByCaretPosition(e) {
437
+ this.selectedCounterIdx = this.getCounterIdx(e.target.selectionStart);
438
+ }
439
+
440
+ selectNextCounter() {
441
+ if (this.selectedCounterIdx < this.dateCounters.length) {
442
+ this.selectedCounterIdx = Math.min(this.selectedCounterIdx + 1, 2);
443
+ }
444
+ }
445
+
446
+ selectPrevCounter() {
447
+ if (this.selectedCounterIdx > 0) {
448
+ this.selectedCounterIdx = Math.min(this.selectedCounterIdx - 1, 1);
449
+ }
450
+ }
451
+
452
+ // Sets the text selection range in the input element based on the selected counter.
453
+ // The function calculates the starting position of the selection by summing the lengths
454
+ // of all counters before the currently selected counter (`selectedCounterIdx`).
455
+ // It then selects the entire length of the current counter in the input element.
456
+ setInputSelectionRange() {
457
+ // For preview/readonly state we don't have a caret or a caretIdx, so we skip setting input selection range
458
+ if (this.selectedCounterIdx < 0) {
459
+ return;
460
+ }
461
+
462
+ const caretStart = this.sortedCounters
463
+ .slice(0, this.selectedCounterIdx)
464
+ .reduce((acc, counter) => acc + counter.length, this.selectedCounterIdx);
465
+
466
+ this.inputElement.setSelectionRange(
467
+ caretStart,
468
+ caretStart + this.sortedCounters[this.selectedCounterIdx].length
469
+ );
470
+ }
471
+
472
+ resetDateCounters() {
473
+ this.dateCounters.forEach((dc) => dc.clear());
474
+ }
475
+
476
+ // in case value is set from external source we need to update date counters
477
+ updateDateCounters(date) {
478
+ this.dateCounters.forEach((dc) => {
479
+ switch (dc.id) {
480
+ case counterConfig.MONTH.id:
481
+ dc.set(date.getMonth() + 1);
482
+ break;
483
+ case counterConfig.YEAR.id:
484
+ dc.set(date.getFullYear());
485
+ break;
486
+ case counterConfig.DAY.id:
487
+ dc.set(date.getDate());
488
+ break;
489
+ default:
490
+ break;
491
+ }
492
+ });
493
+ }
494
+
495
+ handleKeyDownValueChange(e) {
496
+ if (this.isReadOnly) {
497
+ return;
498
+ }
499
+
500
+ const { key, shiftKey, metaKey } = e;
501
+ const keys = getKeyMap(key, shiftKey, metaKey);
502
+ const allowedOperations = keys.refresh || keys.tab || keys.shiftTab;
503
+
504
+ if (this.opened) {
505
+ this.closePopover();
506
+ }
507
+
508
+ if (isSupportedKey(key)) {
509
+ e.preventDefault();
510
+ const counter = this.activeCounter;
511
+
512
+ if (!counter) return;
513
+
514
+ const counterData = Object.values(counterConfig).find((config) => config.id === counter.id);
515
+ const { count, shiftCount } = counterData;
516
+
517
+ if (keys.backspace) this.handleBackspace();
518
+ else if (keys.arrowUp) counter.inc();
519
+ else if (keys.arrowDown) counter.dec();
520
+ else if (keys.shiftArrowUp) counter.inc(count);
521
+ else if (keys.shiftArrowDown) counter.dec(count);
522
+ else if (keys.pageUp) counter.inc(count);
523
+ else if (keys.pageDown) counter.dec(count);
524
+ else if (keys.shiftPageUp) counter.inc(shiftCount);
525
+ else if (keys.shiftPageDown) counter.dec(shiftCount);
526
+
527
+ this.inputElement.value = this.countersValue;
528
+
529
+ this.setInputSelectionRange();
530
+ } else if (!allowedOperations) {
531
+ e.preventDefault();
532
+ }
533
+ }
534
+
535
+ handleBackspace() {
536
+ const counter = this.activeCounter;
537
+
538
+ if (counter.isEmpty) {
539
+ this.selectPrevCounter();
540
+ this.setInputSelectionRange();
541
+ } else {
542
+ counter.del();
543
+ }
544
+ }
545
+
546
+ handleKeydownCaretPositionChange(e) {
547
+ if (this.opened) {
548
+ return;
549
+ }
550
+
551
+ const { key } = e;
552
+
553
+ if (isSupportedKey(key)) {
554
+ e.preventDefault();
555
+
556
+ const keys = getKeyMap(key, false);
557
+
558
+ if (keys.arrowRight) this.selectNextCounter();
559
+ else if (keys.arrowLeft) this.selectPrevCounter();
560
+
561
+ this.setInputSelectionRange();
562
+ }
563
+ }
564
+
565
+ handleMouseCaretPositionChange(e) {
566
+ if (this.opened) {
567
+ return;
568
+ }
569
+ e.preventDefault();
570
+ this.setSelectedCounterByCaretPosition(e);
571
+ this.setInputSelectionRange();
572
+ }
573
+
574
+ onInitialValueChange(val) {
575
+ // if component already has a value don't re-set value
576
+ if (this.value) return;
577
+
578
+ // we need to wait for the text-field to init
579
+ setTimeout(() => {
580
+ this.value = val;
581
+ });
582
+ }
583
+
584
+ attributeChangedCallback(attrName, oldValue, newValue) {
585
+ super.attributeChangedCallback?.(attrName, oldValue, newValue);
586
+
587
+ if (oldValue !== newValue) {
588
+ if (dateFieldAttrs.includes(attrName)) {
589
+ if (newValue && attrName === 'format') {
590
+ this.onFormatUpdate(newValue);
591
+ }
592
+ if (attrName === 'initial-value') {
593
+ this.onInitialValueChange(newValue);
594
+ }
595
+ } else if (calendarAttrs.includes(attrName)) {
596
+ if (newValue) {
597
+ this.calendar?.setAttribute(attrName, newValue);
598
+ } else {
599
+ this.calendar?.removeAttribute(attrName);
600
+ }
601
+ }
602
+ }
603
+ }
604
+
605
+ getValidity() {
606
+ if (this.isRequired && !this.inputElement.value) {
607
+ return { valueMissing: true };
608
+ }
609
+
610
+ return {};
611
+ }
612
+ }
613
+
614
+ const { host, input, toggleButton, overlayAnchor, overlayAnchorRTL, overlay, backdrop } = {
615
+ host: { selector: () => ':host' },
616
+ input: { selector: () => 'descope-text-field' },
617
+ toggleButton: { selector: () => '.toggle-calendar' },
618
+ overlayAnchor: { selector: () => ':host .overlay-position-anchor' },
619
+ overlayAnchorRTL: { selector: ':host([st-host-direction="rtl"]) .overlay-position-anchor' },
620
+ overlay: { selector: 'vaadin-popover-overlay::part(overlay)' },
621
+ backdrop: { selector: 'vaadin-popover-overlay::part(backdrop)' },
622
+ };
623
+
624
+ export const DateFieldClass = compose(
625
+ createStyleMixin({ componentNameOverride: getComponentName('input-wrapper') }),
626
+ createStyleMixin({
627
+ mappings: {
628
+ iconMargin: { ...toggleButton, property: 'margin-inline-end' },
629
+ hostWidth: { ...host, property: 'width' },
630
+ hostDirection: { ...host, property: 'direction' },
631
+ textAlign: { ...input, property: 'text-align' },
632
+ overlayAnchorPos: [
633
+ { ...overlayAnchor, property: 'right' },
634
+ { ...overlayAnchorRTL, property: 'left' },
635
+ ],
636
+ overlayGap: {
637
+ property: () => DateFieldClass.cssVarList.overlayGap,
638
+ },
639
+
640
+ overlayBackgroundColor: {
641
+ property: () => DateFieldClass.cssVarList.overlayBackgroundColor,
642
+ },
643
+ overlayPadding: {
644
+ property: () => DateFieldClass.cssVarList.overlayPadding,
645
+ },
646
+ overlayBoxShadow: { property: () => DateFieldClass.overlayBoxShadow },
647
+ overlayOutlineWidth: {
648
+ property: () => DateFieldClass.cssVarList.overlayOutlineWidth,
649
+ },
650
+ overlayOutlineColor: {
651
+ property: () => DateFieldClass.cssVarList.overlayOutlineColor,
652
+ },
653
+ overlayOutlineStyle: {
654
+ property: () => DateFieldClass.cssVarList.overlayOutlineStyle,
655
+ },
656
+ },
657
+ }),
658
+ portalMixin({
659
+ name: 'overlay',
660
+ selector: '',
661
+ mappings: {
662
+ marginTop: { ...overlay, property: 'margin-top' },
663
+ backgroundColor: { ...overlay },
664
+ backdropBackgroundColor: { ...backdrop, property: 'background-color' },
665
+ backdropPointerEvents: { ...backdrop, property: 'pointer-events' },
666
+ padding: { ...overlay },
667
+ boxShadow: { ...overlay },
668
+ outlineWidth: { ...overlay },
669
+ outlineColor: { ...overlay },
670
+ outlineStyle: { ...overlay },
671
+ },
672
+ }),
673
+ draggableMixin,
674
+ componentNameValidationMixin
675
+ )(RawDateFieldClass);