@descope/web-components-ui 1.0.378 → 1.0.380

Sign up to get free protection for your applications and to get access to all the features.
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);