@descope/web-components-ui 1.105.0 → 1.106.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@descope/web-components-ui",
3
- "version": "1.105.0",
3
+ "version": "1.106.0",
4
4
  "description": "",
5
5
  "main": "dist/cjs/index.cjs.js",
6
6
  "module": "dist/index.esm.js",
@@ -82,14 +82,14 @@
82
82
  "@descope-ui/descope-icon": "0.0.14",
83
83
  "@descope-ui/descope-text": "0.0.17",
84
84
  "@descope-ui/descope-avatar": "0.0.17",
85
- "@descope-ui/descope-combo-box": "0.1.6",
86
- "@descope-ui/descope-autocomplete-field": "0.0.19",
87
- "@descope-ui/descope-address-field": "0.0.18",
88
- "@descope-ui/descope-timer": "0.0.13",
89
- "@descope-ui/descope-timer-button": "0.0.15",
90
- "@descope-ui/descope-password-strength": "0.0.10",
91
- "@descope-ui/descope-collapsible-container": "0.0.14",
92
- "@descope-ui/descope-recovery-codes": "0.0.3"
85
+ "@descope-ui/descope-combo-box": "0.1.7",
86
+ "@descope-ui/descope-autocomplete-field": "0.0.20",
87
+ "@descope-ui/descope-address-field": "0.0.19",
88
+ "@descope-ui/descope-timer": "0.0.14",
89
+ "@descope-ui/descope-timer-button": "0.0.16",
90
+ "@descope-ui/descope-password-strength": "0.0.11",
91
+ "@descope-ui/descope-collapsible-container": "0.0.15",
92
+ "@descope-ui/descope-recovery-codes": "0.0.4"
93
93
  },
94
94
  "overrides": {
95
95
  "@vaadin/avatar": "24.3.4",
@@ -28,6 +28,7 @@ import {
28
28
  import { DateCounter } from './DateCounterClass';
29
29
  import { TextFieldClass } from '../descope-text-field/TextFieldClass';
30
30
  import { injectStyle } from '@descope-ui/common/components-helpers';
31
+ import { parseDateString } from './helpers';
31
32
 
32
33
  export const componentName = getComponentName('date-field');
33
34
 
@@ -220,6 +221,11 @@ class RawDateFieldClass extends BaseInputClass {
220
221
  return this.getAttribute('disable-calendar') === 'true';
221
222
  }
222
223
 
224
+ get isSelectAll() {
225
+ const inputEle = this.inputElement.baseElement.inputElement;
226
+ return inputEle.value.length === inputEle.selectionStart + inputEle.selectionEnd;
227
+ }
228
+
223
229
  reportValidity() {
224
230
  this.inputElement.reportValidity();
225
231
  }
@@ -254,9 +260,10 @@ class RawDateFieldClass extends BaseInputClass {
254
260
  this.inputElement.addEventListener('focus', this.onFocus.bind(this));
255
261
  this.inputElement.addEventListener('blur', this.onBlur.bind(this));
256
262
  this.inputElement.addEventListener('click', this.handleMouseCaretPositionChange.bind(this));
257
- this.inputElement.addEventListener('keydown', this.handleArrowKeys.bind(this));
263
+ this.inputElement.addEventListener('keydown', this.handleKeyboard.bind(this));
258
264
  this.inputElement.addEventListener('beforeinput', this.handleInput.bind(this));
259
265
  this.inputElement.addEventListener('pointerdown', this.onPointerDown.bind(this));
266
+ this.inputElement.addEventListener('paste', this.onPaste.bind(this));
260
267
 
261
268
  forwardAttrs(this, this.inputElement, {
262
269
  includeAttrs: [
@@ -285,6 +292,8 @@ class RawDateFieldClass extends BaseInputClass {
285
292
  handleInput(e) {
286
293
  e.preventDefault();
287
294
 
295
+ this.handleSelectAll();
296
+
288
297
  if (e.data && isNumber(e.data)) {
289
298
  this.parseDigits(e.data);
290
299
  this.updateCountersDisplay();
@@ -305,6 +314,12 @@ class RawDateFieldClass extends BaseInputClass {
305
314
  });
306
315
  }
307
316
 
317
+ handleSelectAll() {
318
+ if (this.isSelectAll) {
319
+ this.selectFirstCounter();
320
+ }
321
+ }
322
+
308
323
  #popoverPosStylesheet;
309
324
 
310
325
  #popoverRenderer(root) {
@@ -475,7 +490,8 @@ class RawDateFieldClass extends BaseInputClass {
475
490
  }
476
491
 
477
492
  // On focus select the first counter
478
- this.selectedCounterIdx = 0;
493
+ this.selectFirstCounter();
494
+ // set selection on first counter
479
495
  this.inputElement.setSelectionRange(0, this.sortedCounters[0].length);
480
496
  }
481
497
 
@@ -534,6 +550,10 @@ class RawDateFieldClass extends BaseInputClass {
534
550
  );
535
551
  }
536
552
 
553
+ selectFirstCounter() {
554
+ this.selectedCounterIdx = 0;
555
+ }
556
+
537
557
  selectNextCounter() {
538
558
  if (this.selectedCounterIdx < this.dateCounters.length) {
539
559
  this.selectedCounterIdx = Math.min(this.selectedCounterIdx + 1, 2);
@@ -593,7 +613,17 @@ class RawDateFieldClass extends BaseInputClass {
593
613
  });
594
614
  }
595
615
 
596
- handleArrowKeys(e) {
616
+ handleKeyboard(e) {
617
+ if (e.metaKey || e.ctrlKey) {
618
+ if (e.key.toLowerCase() === 'x') {
619
+ this.onCut(e);
620
+ }
621
+
622
+ return;
623
+ }
624
+
625
+ this.handleSelectAll();
626
+
597
627
  if (e.key === 'ArrowUp') {
598
628
  this.activeCounter.inc();
599
629
  } else if (e.key === 'ArrowDown') {
@@ -626,6 +656,11 @@ class RawDateFieldClass extends BaseInputClass {
626
656
  }
627
657
 
628
658
  handleBackspace() {
659
+ if (this.isSelectAll) {
660
+ this.resetToInitialState();
661
+ return;
662
+ }
663
+
629
664
  const counter = this.activeCounter;
630
665
 
631
666
  if (counter.isEmpty) {
@@ -743,6 +778,62 @@ class RawDateFieldClass extends BaseInputClass {
743
778
 
744
779
  return ret;
745
780
  }
781
+
782
+ resetToInitialState() {
783
+ this.resetDateCounters();
784
+ this.selectFirstCounter();
785
+ this.resetDisplay();
786
+ }
787
+
788
+ onCut(e) {
789
+ e.preventDefault();
790
+
791
+ if (this.isSelectAll) {
792
+ this.#copyToClipboard(this.countersValue);
793
+ this.resetToInitialState();
794
+ } else {
795
+ this.#copyToClipboard(this.activeCounter.stringValue);
796
+ this.activeCounter.set('');
797
+ }
798
+
799
+ this.setInputSelectionRange();
800
+ }
801
+
802
+ #copyToClipboard(value) {
803
+ try {
804
+ navigator.clipboard.writeText(value);
805
+ } catch (err) {
806
+ console.error('Failed to copy date value:', err);
807
+ }
808
+ }
809
+
810
+ onPaste(e) {
811
+ e.preventDefault();
812
+
813
+ const clipboardData = e.clipboardData || window.clipboardData;
814
+ const pastedData = clipboardData.getData('Text');
815
+
816
+ // try paste entire date if valid
817
+ const validDate = parseDateString(pastedData, this.format);
818
+
819
+ if (validDate) {
820
+ this.value = validDate.getTime();
821
+ this.onDateCounterChange();
822
+
823
+ // select all
824
+ setTimeout(() => this.inputElement.setSelectionRange(0, this.inputElement.value.length));
825
+ } else {
826
+ const value = Number(pastedData);
827
+
828
+ // try paste in counter if possible
829
+ if (value && this.activeCounter.min <= value && this.activeCounter.max >= value) {
830
+ // use String to get rid of any zero padding
831
+ this.activeCounter.set(String(value));
832
+
833
+ setTimeout(() => this.setInputSelectionRange());
834
+ }
835
+ }
836
+ }
746
837
  }
747
838
 
748
839
  const textVars = TextFieldClass.cssVarList;
@@ -1,3 +1,5 @@
1
+ import { formats } from './formats';
2
+
1
3
  export const isValidTimestamp = (val) => !Number.isNaN(Number(val));
2
4
 
3
5
  export const isNumber = (val) => !!String(val || '').trim() && !Number.isNaN(Number(val));
@@ -47,3 +49,9 @@ export const overrideConstructedStylesheet = (ele) => {
47
49
  cs.insertRule(':host{display:block!important;}');
48
50
  ele?.shadowRoot?.adoptedStyleSheets?.push(cs);
49
51
  };
52
+
53
+ export const parseDateString = (val, format) => {
54
+ const trimmed = val.trim?.();
55
+ if (!trimmed) return null;
56
+ return formats[format].getDate(trimmed);
57
+ };