@descope/web-components-ui 1.0.358 → 1.0.359

Sign up to get free protection for your applications and to get access to all the features.
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' },
@@ -2870,18 +2876,46 @@ const NumberFieldClass = compose(
2870
2876
 
2871
2877
  customElements.define(componentName$I, NumberFieldClass);
2872
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
+
2873
2883
  const focusElement = (ele) => {
2874
2884
  ele?.focus();
2875
2885
  ele?.setSelectionRange?.(1, 1);
2876
2886
  };
2877
2887
 
2878
- const getSanitizedCharacters = (str) => {
2879
- const pin = str.replace(/\s/g, ''); // sanitize string
2888
+ const sanitizeStr = (str) => {
2889
+ return str.replace(/\D/g, '') || '';
2890
+ };
2880
2891
 
2881
- // accept only numbers
2882
- 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
+ };
2883
2910
 
2884
- 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
+ }
2885
2919
  };
2886
2920
 
2887
2921
  /* eslint-disable no-param-reassign */
@@ -2972,11 +3006,7 @@ class PasscodeInternal extends BaseInputClass$7 {
2972
3006
  set value(val) {
2973
3007
  if (val === this.value) return;
2974
3008
 
2975
- const charArr = getSanitizedCharacters(val);
2976
-
2977
- if (charArr.length) {
2978
- this.fillDigits(charArr, this.inputs[0]);
2979
- }
3009
+ this.parseInputValue(this.inputs[0], sanitizeStr(val));
2980
3010
  }
2981
3011
 
2982
3012
  getValidity() {
@@ -3032,8 +3062,8 @@ class PasscodeInternal extends BaseInputClass$7 {
3032
3062
  focusElement(currentInput);
3033
3063
  }
3034
3064
 
3035
- parseInputValue(input) {
3036
- const charArr = getSanitizedCharacters(input.value);
3065
+ parseInputValue(input, value = '') {
3066
+ const charArr = value.split('');
3037
3067
 
3038
3068
  if (!charArr.length) {
3039
3069
  // if we got an invalid value we want to clear the input
@@ -3045,15 +3075,30 @@ class PasscodeInternal extends BaseInputClass$7 {
3045
3075
  let currentInput;
3046
3076
 
3047
3077
  this.inputs.forEach((input) => {
3078
+ input.shadowRoot.appendChild(createInputMaskStyle());
3079
+
3048
3080
  input.addEventListener('change', (e) => {
3049
3081
  if (currentInput !== e.target) {
3050
- this.parseInputValue(input);
3082
+ this.parseInputValue(input, input.value);
3051
3083
  this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));
3052
3084
  }
3053
3085
  });
3054
3086
 
3087
+ const handleParseInput = (val) => {
3088
+ this.parseInputValue(input, val);
3089
+ toggleMaskVisibility(input);
3090
+ };
3091
+
3092
+ const debouncedHandleParseInput = debounce(handleParseInput, 20, { trailing: true });
3093
+
3055
3094
  // sanitize the input
3056
3095
  input.addEventListener('input', (e) => {
3096
+ input.value = sanitizeStr(input.value);
3097
+
3098
+ if (input.value) {
3099
+ toggleMaskVisibility(input, input.value[0]);
3100
+ }
3101
+
3057
3102
  // when using iPhone's code autofill we get only `change` events.
3058
3103
  // In other scenarios we get `input` AND `change` events.
3059
3104
  // In order to be parse the digits properly in iPhone, we need to listen to `change` event
@@ -3064,12 +3109,11 @@ class PasscodeInternal extends BaseInputClass$7 {
3064
3109
  currentInput = e.target;
3065
3110
  setTimeout(() => {
3066
3111
  currentInput = null;
3067
- if (e.inputType === 'deleteContentBackward') {
3112
+ if (e?.inputType === 'deleteContentBackward') {
3068
3113
  focusElement(this.getPrevInput(input));
3069
3114
  }
3070
3115
  });
3071
-
3072
- this.parseInputValue(input);
3116
+ debouncedHandleParseInput(input.value);
3073
3117
  });
3074
3118
 
3075
3119
  // we want backspace to focus on the previous digit
@@ -3394,10 +3438,15 @@ const PasscodeClass = compose(
3394
3438
  -webkit-mask-image: none;
3395
3439
  }
3396
3440
 
3441
+ /* safari */
3442
+ vaadin-text-field::part(input-field)::after {
3443
+ opacity: 0;
3444
+ }
3445
+
3397
3446
  vaadin-text-field {
3398
3447
  margin: 0;
3399
3448
  padding: 0;
3400
- width: 100%
3449
+ width: 100%;
3401
3450
  }
3402
3451
 
3403
3452
  vaadin-text-field::before {