@descope/web-components-ui 1.0.357 → 1.0.359

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/index.esm.js CHANGED
@@ -4,6 +4,7 @@ import '@vaadin/checkbox';
4
4
  import '@vaadin/text-field';
5
5
  import '@vaadin/email-field';
6
6
  import '@vaadin/number-field';
7
+ import debounce from 'lodash.debounce';
7
8
  import '@vaadin/icons';
8
9
  import '@vaadin/icon';
9
10
  import '@vaadin/password-field';
@@ -2518,6 +2519,7 @@ const {
2518
2519
  requiredIndicator: requiredIndicator$9,
2519
2520
  inputField: inputField$6,
2520
2521
  input,
2522
+ inputMask,
2521
2523
  helperText: helperText$8,
2522
2524
  errorMessage: errorMessage$a,
2523
2525
  disabledPlaceholder,
@@ -2534,6 +2536,7 @@ const {
2534
2536
  disabledPlaceholder: { selector: '> input:disabled::placeholder' },
2535
2537
  inputField: { selector: '::part(input-field)' },
2536
2538
  input: { selector: 'input' },
2539
+ inputMask: { selector: '::part(input-field)::before' },
2537
2540
  inputDisabled: { selector: 'input:disabled' },
2538
2541
  helperText: { selector: '::part(helper-text)' },
2539
2542
  errorMessage: { selector: '::part(error-message)' },
@@ -2559,7 +2562,10 @@ var textFieldMappings = {
2559
2562
  hostMinWidth: { ...host$i, property: 'min-width' },
2560
2563
  hostDirection: { ...host$i, property: 'direction' },
2561
2564
 
2562
- inputBackgroundColor: { ...inputField$6, property: 'background-color' },
2565
+ inputBackgroundColor: [
2566
+ { ...inputField$6, property: 'background-color' },
2567
+ { ...inputMask, property: 'background-color' },
2568
+ ],
2563
2569
 
2564
2570
  errorMessageTextColor: { ...errorMessage$a, property: 'color' },
2565
2571
  helperTextColor: { ...helperText$8, property: '-webkit-text-fill-color' },
@@ -2620,18 +2626,21 @@ var textFieldMappings = {
2620
2626
 
2621
2627
  const componentName$N = getComponentName('email-field');
2622
2628
 
2629
+ const defaultPattern = "^[\\w\\.\\%\\+\\-']+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$";
2630
+ const defaultAutocomplete = 'username';
2631
+
2623
2632
  const customMixin$a = (superclass) =>
2624
2633
  class EmailFieldMixinClass extends superclass {
2625
2634
  init() {
2626
2635
  super.init?.();
2627
2636
 
2628
- this.baseElement.setAttribute('pattern', '^[\\w\\.\\%\\+\\-]+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$');
2629
-
2630
- this.setAttribute('autocomplete', this.getAutocompleteType());
2631
- }
2637
+ if (!this.getAttribute('pattern')) {
2638
+ this.setAttribute('pattern', defaultPattern);
2639
+ }
2632
2640
 
2633
- getAutocompleteType() {
2634
- return this.getAttribute('autocomplete') || 'username';
2641
+ if (!this.getAttribute('autocomplete')) {
2642
+ this.setAttribute('autocomplete', defaultAutocomplete);
2643
+ }
2635
2644
  }
2636
2645
  };
2637
2646
 
@@ -2663,7 +2672,7 @@ const EmailFieldClass = compose(
2663
2672
 
2664
2673
  vaadin-email-field[label-type="floating"]:not([focused])[readonly] > input:placeholder-shown {
2665
2674
  opacity: 0;
2666
- }
2675
+ }
2667
2676
  vaadin-email-field[label-type="floating"]:not([focused])[disabled] > input:placeholder-shown {
2668
2677
  opacity: 0;
2669
2678
  }
@@ -2867,18 +2876,46 @@ const NumberFieldClass = compose(
2867
2876
 
2868
2877
  customElements.define(componentName$I, NumberFieldClass);
2869
2878
 
2879
+ const INPUT_MASK_TEXT_PROP = '--descope-input-mask-content';
2880
+ const INPUT_MASK_DISPLAY_PROP = '--descope-input-mask-display';
2881
+ const INPUT_MASK_FALLBACK_PROP = '--descope-input-mask-fallback';
2882
+
2870
2883
  const focusElement = (ele) => {
2871
2884
  ele?.focus();
2872
2885
  ele?.setSelectionRange?.(1, 1);
2873
2886
  };
2874
2887
 
2875
- const getSanitizedCharacters = (str) => {
2876
- const pin = str.replace(/\s/g, ''); // sanitize string
2888
+ const sanitizeStr = (str) => {
2889
+ return str.replace(/\D/g, '') || '';
2890
+ };
2877
2891
 
2878
- // accept only numbers
2879
- if (!pin.match(/^\d+$/)) return [];
2892
+ // During debounced input we hide the value with a mask.
2893
+ // This allows us to hide the multiple population of the first input
2894
+ // in case of an automated input (e.g. Safari OTP Autofill or paste).
2895
+ const createInputMaskStyle = () => {
2896
+ const ele = document.createElement('style');
2897
+ ele.id = 'input-mask';
2898
+ ele.innerHTML = `vaadin-text-field::part(input-field)::before {
2899
+ ${INPUT_MASK_FALLBACK_PROP}: '';
2900
+ content: var(${INPUT_MASK_TEXT_PROP}, var(${INPUT_MASK_FALLBACK_PROP}));
2901
+ position: absolute;
2902
+ width: 100%;
2903
+ height: 100%;
2904
+ display: var(${INPUT_MASK_DISPLAY_PROP}, none);
2905
+ align-items: center;
2906
+ justify-content: center;
2907
+ }`;
2908
+ return ele;
2909
+ };
2880
2910
 
2881
- return [...pin]; // creating array of chars
2911
+ const toggleMaskVisibility = (input, value) => {
2912
+ if (value) {
2913
+ input.style.setProperty(INPUT_MASK_TEXT_PROP, `"${value}"`);
2914
+ input.style.setProperty(INPUT_MASK_DISPLAY_PROP, 'flex');
2915
+ } else {
2916
+ input.style.removeProperty(INPUT_MASK_TEXT_PROP);
2917
+ input.style.removeProperty(INPUT_MASK_DISPLAY_PROP);
2918
+ }
2882
2919
  };
2883
2920
 
2884
2921
  /* eslint-disable no-param-reassign */
@@ -2969,11 +3006,7 @@ class PasscodeInternal extends BaseInputClass$7 {
2969
3006
  set value(val) {
2970
3007
  if (val === this.value) return;
2971
3008
 
2972
- const charArr = getSanitizedCharacters(val);
2973
-
2974
- if (charArr.length) {
2975
- this.fillDigits(charArr, this.inputs[0]);
2976
- }
3009
+ this.parseInputValue(this.inputs[0], sanitizeStr(val));
2977
3010
  }
2978
3011
 
2979
3012
  getValidity() {
@@ -3029,8 +3062,8 @@ class PasscodeInternal extends BaseInputClass$7 {
3029
3062
  focusElement(currentInput);
3030
3063
  }
3031
3064
 
3032
- parseInputValue(input) {
3033
- const charArr = getSanitizedCharacters(input.value);
3065
+ parseInputValue(input, value = '') {
3066
+ const charArr = value.split('');
3034
3067
 
3035
3068
  if (!charArr.length) {
3036
3069
  // if we got an invalid value we want to clear the input
@@ -3042,15 +3075,30 @@ class PasscodeInternal extends BaseInputClass$7 {
3042
3075
  let currentInput;
3043
3076
 
3044
3077
  this.inputs.forEach((input) => {
3078
+ input.shadowRoot.appendChild(createInputMaskStyle());
3079
+
3045
3080
  input.addEventListener('change', (e) => {
3046
3081
  if (currentInput !== e.target) {
3047
- this.parseInputValue(input);
3082
+ this.parseInputValue(input, input.value);
3048
3083
  this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
3049
3084
  }
3050
3085
  });
3051
3086
 
3087
+ const handleParseInput = (val) => {
3088
+ this.parseInputValue(input, val);
3089
+ toggleMaskVisibility(input);
3090
+ };
3091
+
3092
+ const debouncedHandleParseInput = debounce(handleParseInput, 20, { trailing: true });
3093
+
3052
3094
  // sanitize the input
3053
3095
  input.addEventListener('input', (e) => {
3096
+ input.value = sanitizeStr(input.value);
3097
+
3098
+ if (input.value) {
3099
+ toggleMaskVisibility(input, input.value[0]);
3100
+ }
3101
+
3054
3102
  // when using iPhone's code autofill we get only `change` events.
3055
3103
  // In other scenarios we get `input` AND `change` events.
3056
3104
  // In order to be parse the digits properly in iPhone, we need to listen to `change` event
@@ -3061,12 +3109,11 @@ class PasscodeInternal extends BaseInputClass$7 {
3061
3109
  currentInput = e.target;
3062
3110
  setTimeout(() => {
3063
3111
  currentInput = null;
3064
- if (e.inputType === 'deleteContentBackward') {
3112
+ if (e?.inputType === 'deleteContentBackward') {
3065
3113
  focusElement(this.getPrevInput(input));
3066
3114
  }
3067
3115
  });
3068
-
3069
- this.parseInputValue(input);
3116
+ debouncedHandleParseInput(input.value);
3070
3117
  });
3071
3118
 
3072
3119
  // we want backspace to focus on the previous digit
@@ -3391,10 +3438,15 @@ const PasscodeClass = compose(
3391
3438
  -webkit-mask-image: none;
3392
3439
  }
3393
3440
 
3441
+ /* safari */
3442
+ vaadin-text-field::part(input-field)::after {
3443
+ opacity: 0;
3444
+ }
3445
+
3394
3446
  vaadin-text-field {
3395
3447
  margin: 0;
3396
3448
  padding: 0;
3397
- width: 100%
3449
+ width: 100%;
3398
3450
  }
3399
3451
 
3400
3452
  vaadin-text-field::before {