@descope/web-components-ui 1.88.0 → 1.90.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.
- package/dist/cjs/index.cjs.js +181 -104
- package/dist/cjs/index.cjs.js.map +1 -1
- package/dist/index.esm.js +181 -104
- package/dist/index.esm.js.map +1 -1
- package/dist/umd/8961.js.map +1 -1
- package/dist/umd/DescopeDev.js +1 -1
- package/dist/umd/DescopeDev.js.map +1 -1
- package/dist/umd/descope-date-field-descope-calendar-index-js.js +1 -1
- package/dist/umd/descope-date-field-descope-calendar-index-js.js.map +1 -1
- package/dist/umd/descope-date-field-index-js.js +1 -1
- package/dist/umd/descope-date-field-index-js.js.map +1 -1
- package/package.json +14 -14
- package/src/components/descope-date-field/DateCounterClass.js +42 -11
- package/src/components/descope-date-field/DateFieldClass.js +125 -89
- package/src/components/descope-date-field/consts.js +2 -1
- package/src/components/descope-date-field/helpers.js +2 -1
- package/src/theme/components/dateField.js +7 -0
@@ -42,10 +42,40 @@ class RawDateFieldClass extends BaseInputClass {
|
|
42
42
|
|
43
43
|
selectedCounterIdx = 0;
|
44
44
|
|
45
|
+
updateCountersDisplay() {
|
46
|
+
this.inputElement.value = this.countersValue;
|
47
|
+
}
|
48
|
+
|
49
|
+
updateValue() {
|
50
|
+
if (this.isCountersOutOfRange) {
|
51
|
+
this.updateTimestamp('');
|
52
|
+
} else {
|
53
|
+
const date = formats[this.format].getDate(this.inputElement.value);
|
54
|
+
this.updateTimestamp(date.getTime());
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
onDateCounterChange = () => {
|
59
|
+
this.updateCountersDisplay();
|
60
|
+
this.updateValue();
|
61
|
+
// update validity
|
62
|
+
this.#dispatchInput();
|
63
|
+
};
|
64
|
+
|
65
|
+
updateTimestamp(epochOrDate) {
|
66
|
+
if (!epochOrDate) {
|
67
|
+
this.timestamp = '';
|
68
|
+
} else {
|
69
|
+
this.timestamp = newDate(epochOrDate).getTime();
|
70
|
+
}
|
71
|
+
}
|
72
|
+
|
73
|
+
#yearDateCounter = new DateCounter(counterConfig.YEAR, this.onDateCounterChange.bind(this));
|
74
|
+
|
45
75
|
dateCounters = [
|
46
|
-
new DateCounter(counterConfig.MONTH),
|
47
|
-
new DateCounter(counterConfig.DAY),
|
48
|
-
|
76
|
+
new DateCounter(counterConfig.MONTH, this.onDateCounterChange.bind(this)),
|
77
|
+
new DateCounter(counterConfig.DAY, this.onDateCounterChange.bind(this)),
|
78
|
+
this.#yearDateCounter,
|
49
79
|
];
|
50
80
|
|
51
81
|
static get observedAttributes() {
|
@@ -97,11 +127,10 @@ class RawDateFieldClass extends BaseInputClass {
|
|
97
127
|
|
98
128
|
this.inputElement = this.shadowRoot.querySelector('descope-text-field');
|
99
129
|
this.popoverToggleButton = this.inputElement.querySelector('.toggle-calendar');
|
130
|
+
}
|
100
131
|
|
101
|
-
|
102
|
-
|
103
|
-
this.inputElement.focus();
|
104
|
-
};
|
132
|
+
get validationTarget() {
|
133
|
+
return this.inputElement;
|
105
134
|
}
|
106
135
|
|
107
136
|
get opened() {
|
@@ -109,7 +138,7 @@ class RawDateFieldClass extends BaseInputClass {
|
|
109
138
|
}
|
110
139
|
|
111
140
|
// returns the input's value as a timestamp
|
112
|
-
get
|
141
|
+
get displayValueEpoch() {
|
113
142
|
const date = formats[this.format].getDate(this.inputElement.value);
|
114
143
|
|
115
144
|
if (!isValidTimestamp(date?.getTime())) {
|
@@ -161,37 +190,32 @@ class RawDateFieldClass extends BaseInputClass {
|
|
161
190
|
}
|
162
191
|
|
163
192
|
set value(val) {
|
164
|
-
if (
|
165
|
-
|
166
|
-
|
167
|
-
const isValTimestamp = !Number.isNaN(numVal);
|
168
|
-
|
169
|
-
let date;
|
170
|
-
let timestamp;
|
171
|
-
|
172
|
-
if (isValTimestamp) {
|
173
|
-
date = newDate(numVal);
|
174
|
-
timestamp = numVal;
|
193
|
+
if (val) {
|
194
|
+
this.updateTimestamp(val);
|
195
|
+
this.updateDateCounters(newDate(val));
|
175
196
|
} else {
|
176
|
-
|
177
|
-
timestamp = date.getTime();
|
197
|
+
this.updateTimestamp('');
|
178
198
|
}
|
199
|
+
}
|
179
200
|
|
180
|
-
|
181
|
-
|
182
|
-
|
201
|
+
get isCountersEmpty() {
|
202
|
+
return this.dateCounters.every((dc) => dc.isEmpty);
|
203
|
+
}
|
183
204
|
|
184
|
-
|
205
|
+
get isCountersOutOfRange() {
|
206
|
+
return this.dateCounters.some((dc) => !dc.isInRange(dc.numberValue));
|
207
|
+
}
|
185
208
|
|
186
|
-
|
187
|
-
this.
|
209
|
+
reportValidity() {
|
210
|
+
this.inputElement.reportValidity();
|
211
|
+
}
|
188
212
|
|
189
|
-
|
190
|
-
this.dispatchEvent(new Event('input'));
|
213
|
+
#dispatchInput() {
|
214
|
+
this.inputElement.baseElement.dispatchEvent(new Event('input', { bubbles: true }));
|
191
215
|
}
|
192
216
|
|
193
217
|
updateInputDisplay() {
|
194
|
-
this.inputElement.value = formatTimestamp(newDate(this.
|
218
|
+
this.inputElement.value = formatTimestamp(newDate(this.countersValue).getTime(), this.format);
|
195
219
|
}
|
196
220
|
|
197
221
|
init() {
|
@@ -199,6 +223,7 @@ class RawDateFieldClass extends BaseInputClass {
|
|
199
223
|
|
200
224
|
this.updateFormatPattern();
|
201
225
|
this.initPopover();
|
226
|
+
this.onDateCounterChange();
|
202
227
|
this.initInputElement();
|
203
228
|
|
204
229
|
setTimeout(() => {
|
@@ -207,15 +232,16 @@ class RawDateFieldClass extends BaseInputClass {
|
|
207
232
|
}
|
208
233
|
|
209
234
|
initInputElement() {
|
235
|
+
this.inputElement.getValidity = this.getValidity.bind(this);
|
236
|
+
this.inputElement.baseElement.checkValidity = this.checkValidity.bind(this);
|
237
|
+
|
210
238
|
this.popoverToggleButton.addEventListener('click', this.onPopoverToggle.bind(this));
|
211
239
|
|
212
240
|
this.inputElement.addEventListener('focus', this.onFocus.bind(this));
|
213
241
|
this.inputElement.addEventListener('blur', this.onBlur.bind(this));
|
214
|
-
this.inputElement.addEventListener('input', this.onInput.bind(this));
|
215
242
|
this.inputElement.addEventListener('click', this.handleMouseCaretPositionChange.bind(this));
|
216
|
-
this.inputElement.addEventListener('keydown', this.
|
217
|
-
this.inputElement.addEventListener('keydown', this.
|
218
|
-
this.inputElement.addEventListener('keydown', this.handleValueChange.bind(this));
|
243
|
+
this.inputElement.addEventListener('keydown', this.handleNavKeys.bind(this));
|
244
|
+
this.inputElement.addEventListener('keydown', this.handleDigitKeys.bind(this));
|
219
245
|
|
220
246
|
forwardAttrs(this, this.inputElement, {
|
221
247
|
includeAttrs: [
|
@@ -229,8 +255,14 @@ class RawDateFieldClass extends BaseInputClass {
|
|
229
255
|
'full-width',
|
230
256
|
'st-host-direction',
|
231
257
|
'pattern',
|
232
|
-
'invalid',
|
233
258
|
'bordered',
|
259
|
+
'data-errormessage-value-missing',
|
260
|
+
'data-errormessage-pattern-mismatch',
|
261
|
+
'data-errormessage-range-underflow',
|
262
|
+
'data-errormessage-range-overflow',
|
263
|
+
'st-error-message-icon',
|
264
|
+
'st-error-message-icon-size',
|
265
|
+
'st-error-message-icon-padding',
|
234
266
|
],
|
235
267
|
});
|
236
268
|
}
|
@@ -358,7 +390,7 @@ class RawDateFieldClass extends BaseInputClass {
|
|
358
390
|
this.getCounterById('month').replaceValue(calendarDate.getMonth() + 1);
|
359
391
|
this.getCounterById('day').replaceValue(calendarDate.getDate());
|
360
392
|
|
361
|
-
this
|
393
|
+
this.#dispatchInput();
|
362
394
|
}
|
363
395
|
|
364
396
|
this.closePopover();
|
@@ -369,10 +401,10 @@ class RawDateFieldClass extends BaseInputClass {
|
|
369
401
|
isValidTimestamp(newDate(this.inputElement.value || '').getTime()) &&
|
370
402
|
formats[this.format].validate(this.inputElement.value);
|
371
403
|
|
372
|
-
if (this.
|
404
|
+
if (this.displayValueEpoch || validInputVal) {
|
373
405
|
this.calendar.setAttribute(
|
374
406
|
'initial-value',
|
375
|
-
formatTimestamp(this.
|
407
|
+
formatTimestamp(this.displayValueEpoch || this.timestamp, NATIVE_FORMAT)
|
376
408
|
);
|
377
409
|
} else {
|
378
410
|
this.calendar.clearValue();
|
@@ -395,13 +427,6 @@ class RawDateFieldClass extends BaseInputClass {
|
|
395
427
|
});
|
396
428
|
}
|
397
429
|
|
398
|
-
onInput(e) {
|
399
|
-
if (!e.target.value) {
|
400
|
-
this.calendar?.clear();
|
401
|
-
this.calendar?.renderCalendar();
|
402
|
-
}
|
403
|
-
}
|
404
|
-
|
405
430
|
onFocus() {
|
406
431
|
if (this.isReadOnly) {
|
407
432
|
return;
|
@@ -413,16 +438,13 @@ class RawDateFieldClass extends BaseInputClass {
|
|
413
438
|
}
|
414
439
|
}
|
415
440
|
|
416
|
-
clearInputValue() {
|
417
|
-
this.inputElement.value = '';
|
418
|
-
this.resetDateCounters();
|
419
|
-
}
|
420
|
-
|
421
441
|
onBlur() {
|
422
|
-
if (this.
|
423
|
-
|
424
|
-
}
|
425
|
-
|
442
|
+
if (this.opened) {
|
443
|
+
return;
|
444
|
+
}
|
445
|
+
|
446
|
+
if (this.inputElement.value === this.format) {
|
447
|
+
this.inputElement.value = '';
|
426
448
|
}
|
427
449
|
}
|
428
450
|
|
@@ -439,11 +461,11 @@ class RawDateFieldClass extends BaseInputClass {
|
|
439
461
|
this.setAttribute('pattern', formats[format].pattern);
|
440
462
|
}
|
441
463
|
|
442
|
-
|
464
|
+
handleDigitKeys(e) {
|
443
465
|
if (isNumber(e.key)) {
|
444
466
|
e.preventDefault();
|
445
467
|
|
446
|
-
this.
|
468
|
+
this.activeCounter.add(e.key);
|
447
469
|
|
448
470
|
if (this.activeCounter.isFull) {
|
449
471
|
this.selectNextCounter();
|
@@ -463,11 +485,6 @@ class RawDateFieldClass extends BaseInputClass {
|
|
463
485
|
return [c1, c2, c3].indexOf(true);
|
464
486
|
}
|
465
487
|
|
466
|
-
handleCountersValue(val) {
|
467
|
-
this.activeCounter.add(val);
|
468
|
-
this.inputElement.value = this.countersValue;
|
469
|
-
}
|
470
|
-
|
471
488
|
setSelectedCounterByCaretPosition(e) {
|
472
489
|
this.selectedCounterIdx = this.getCounterIdx(e.target.selectionStart);
|
473
490
|
}
|
@@ -527,21 +544,21 @@ class RawDateFieldClass extends BaseInputClass {
|
|
527
544
|
});
|
528
545
|
}
|
529
546
|
|
530
|
-
|
547
|
+
handleNavKeys(e) {
|
531
548
|
if (this.isReadOnly) {
|
532
549
|
return;
|
533
550
|
}
|
534
551
|
|
535
552
|
const { key, shiftKey, metaKey } = e;
|
536
553
|
const keys = getKeyMap(key, shiftKey, metaKey);
|
537
|
-
const allowedOperations = keys.refresh || keys.tab || keys.shiftTab;
|
538
554
|
|
539
555
|
if (this.opened) {
|
540
556
|
this.closePopover();
|
541
557
|
}
|
542
558
|
|
559
|
+
e.preventDefault();
|
560
|
+
|
543
561
|
if (isSupportedKey(key)) {
|
544
|
-
e.preventDefault();
|
545
562
|
const counter = this.activeCounter;
|
546
563
|
|
547
564
|
if (!counter) return;
|
@@ -558,12 +575,10 @@ class RawDateFieldClass extends BaseInputClass {
|
|
558
575
|
else if (keys.pageDown) counter.dec(count);
|
559
576
|
else if (keys.shiftPageUp) counter.inc(shiftCount);
|
560
577
|
else if (keys.shiftPageDown) counter.dec(shiftCount);
|
561
|
-
|
562
|
-
|
578
|
+
else if (keys.arrowRight) this.selectNextCounter();
|
579
|
+
else if (keys.arrowLeft) this.selectPrevCounter();
|
563
580
|
|
564
581
|
this.setInputSelectionRange();
|
565
|
-
} else if (!allowedOperations) {
|
566
|
-
e.preventDefault();
|
567
582
|
}
|
568
583
|
}
|
569
584
|
|
@@ -578,25 +593,6 @@ class RawDateFieldClass extends BaseInputClass {
|
|
578
593
|
}
|
579
594
|
}
|
580
595
|
|
581
|
-
handleKeydownCaretPositionChange(e) {
|
582
|
-
if (this.opened) {
|
583
|
-
return;
|
584
|
-
}
|
585
|
-
|
586
|
-
const { key } = e;
|
587
|
-
|
588
|
-
if (isSupportedKey(key)) {
|
589
|
-
e.preventDefault();
|
590
|
-
|
591
|
-
const keys = getKeyMap(key, false);
|
592
|
-
|
593
|
-
if (keys.arrowRight) this.selectNextCounter();
|
594
|
-
else if (keys.arrowLeft) this.selectPrevCounter();
|
595
|
-
|
596
|
-
this.setInputSelectionRange();
|
597
|
-
}
|
598
|
-
}
|
599
|
-
|
600
596
|
handleMouseCaretPositionChange(e) {
|
601
597
|
if (this.opened) {
|
602
598
|
return;
|
@@ -616,10 +612,22 @@ class RawDateFieldClass extends BaseInputClass {
|
|
616
612
|
});
|
617
613
|
}
|
618
614
|
|
615
|
+
setYearRange(val) {
|
616
|
+
if (!val) return;
|
617
|
+
const [min, max] = val.split?.('-');
|
618
|
+
if (min && max) {
|
619
|
+
this.#yearDateCounter.setMin(min);
|
620
|
+
this.#yearDateCounter.setMax(max);
|
621
|
+
}
|
622
|
+
}
|
623
|
+
|
619
624
|
attributeChangedCallback(attrName, oldValue, newValue) {
|
620
625
|
super.attributeChangedCallback?.(attrName, oldValue, newValue);
|
621
626
|
|
622
627
|
if (oldValue !== newValue) {
|
628
|
+
if (attrName === 'years-range') {
|
629
|
+
this.setYearRange(newValue);
|
630
|
+
}
|
623
631
|
if (dateFieldAttrs.includes(attrName)) {
|
624
632
|
if (newValue && attrName === 'format') {
|
625
633
|
this.onFormatUpdate(newValue);
|
@@ -638,16 +646,20 @@ class RawDateFieldClass extends BaseInputClass {
|
|
638
646
|
}
|
639
647
|
|
640
648
|
getValidity() {
|
641
|
-
if (this.isRequired &&
|
649
|
+
if (this.isRequired && this.isCountersEmpty) {
|
642
650
|
return { valueMissing: true };
|
643
651
|
}
|
644
652
|
|
653
|
+
if (this.isCountersOutOfRange) {
|
654
|
+
return { patternMismatch: true };
|
655
|
+
}
|
656
|
+
|
645
657
|
return {};
|
646
658
|
}
|
647
659
|
}
|
648
660
|
|
649
661
|
const textVars = TextFieldClass.cssVarList;
|
650
|
-
const { host, input, inputEleRTL, toggleButton, overlay, backdrop } = {
|
662
|
+
const { host, input, inputEleRTL, toggleButton, overlay, backdrop, errorMessage } = {
|
651
663
|
host: { selector: () => ':host' },
|
652
664
|
input: { selector: () => 'descope-text-field' },
|
653
665
|
inputEleRTL: { selector: () => ':host([st-host-direction="rtl"]) descope-text-field' },
|
@@ -685,6 +697,30 @@ export const DateFieldClass = compose(
|
|
685
697
|
overlayOutlineStyle: {
|
686
698
|
property: () => DateFieldClass.cssVarList.overlayOutlineStyle,
|
687
699
|
},
|
700
|
+
errorMessageIcon: {
|
701
|
+
selector: TextFieldClass.componentName,
|
702
|
+
property: TextFieldClass.cssVarList.errorMessageIcon,
|
703
|
+
},
|
704
|
+
errorMessageIconSize: {
|
705
|
+
selector: TextFieldClass.componentName,
|
706
|
+
property: TextFieldClass.cssVarList.errorMessageIconSize,
|
707
|
+
},
|
708
|
+
errorMessageIconPadding: {
|
709
|
+
selector: TextFieldClass.componentName,
|
710
|
+
property: TextFieldClass.cssVarList.errorMessageIconPadding,
|
711
|
+
},
|
712
|
+
errorMessageIconRepeat: {
|
713
|
+
selector: TextFieldClass.componentName,
|
714
|
+
property: TextFieldClass.cssVarList.errorMessageIconRepeat,
|
715
|
+
},
|
716
|
+
errorMessageIconPosition: {
|
717
|
+
selector: TextFieldClass.componentName,
|
718
|
+
property: TextFieldClass.cssVarList.errorMessageIconPosition,
|
719
|
+
},
|
720
|
+
errorMessageFontSize: {
|
721
|
+
selector: TextFieldClass.componentName,
|
722
|
+
property: TextFieldClass.cssVarList.errorMessageFontSize,
|
723
|
+
},
|
688
724
|
},
|
689
725
|
}),
|
690
726
|
portalMixin({
|
@@ -17,6 +17,7 @@ export const COUNTER_SUPPORTED_KEYS = [
|
|
17
17
|
'PageUp',
|
18
18
|
'PageDown',
|
19
19
|
'Meta',
|
20
|
+
'Enter',
|
20
21
|
];
|
21
22
|
|
22
23
|
export const months = [
|
@@ -47,7 +48,7 @@ export const weekdays = [
|
|
47
48
|
export const counterConfig = {
|
48
49
|
MONTH: { id: 'month', min: 1, max: 12, placeholder: 'MM', count: 5, shiftCount: 10 },
|
49
50
|
DAY: { id: 'day', min: 1, max: 31, placeholder: 'DD', count: 5, shiftCount: 10 },
|
50
|
-
YEAR: { id: 'year', min:
|
51
|
+
YEAR: { id: 'year', min: 1900, max: 2099, placeholder: 'YYYY', count: 10, shiftCount: 100 },
|
51
52
|
};
|
52
53
|
|
53
54
|
export const BUTTON_LABEL_DONE = 'Done';
|
@@ -5,7 +5,7 @@ export const isValidTimestamp = (val) => !Number.isNaN(Number(val));
|
|
5
5
|
export const isNumber = (val) => !Number.isNaN(Number(val));
|
6
6
|
|
7
7
|
export const getTimestampParts = (timestamp) => {
|
8
|
-
const date =
|
8
|
+
const date = newDate(timestamp);
|
9
9
|
const year = date.getFullYear();
|
10
10
|
const month = date.getMonth() + 1;
|
11
11
|
const day = date.getDate();
|
@@ -53,6 +53,7 @@ export const getKeyMap = (key, shiftKey, metaKey) => {
|
|
53
53
|
shiftArrowDown: shiftKey && key === 'ArrowDown',
|
54
54
|
shiftPageUp: shiftKey && key === 'PageUp',
|
55
55
|
shiftPageDown: shiftKey && key === 'PageDown',
|
56
|
+
enter: key === 'Enter',
|
56
57
|
};
|
57
58
|
};
|
58
59
|
|
@@ -26,6 +26,13 @@ const dateField = {
|
|
26
26
|
|
27
27
|
[vars.rtlInputDirection]: 'ltr',
|
28
28
|
[vars.rtlInputAlignment]: 'right',
|
29
|
+
|
30
|
+
[vars.errorMessageIcon]: refs.errorMessageIcon,
|
31
|
+
[vars.errorMessageIconSize]: refs.errorMessageIconSize,
|
32
|
+
[vars.errorMessageIconPadding]: refs.errorMessageIconPadding,
|
33
|
+
[vars.errorMessageIconRepeat]: refs.errorMessageIconRepeat,
|
34
|
+
[vars.errorMessageIconPosition]: refs.errorMessageIconPosition,
|
35
|
+
[vars.errorMessageFontSize]: refs.errorMessageFontSize,
|
29
36
|
};
|
30
37
|
|
31
38
|
export default dateField;
|