@descope/web-components-ui 1.0.320 → 1.0.322

Sign up to get free protection for your applications and to get access to all the features.
@@ -3412,18 +3412,18 @@ const createExternalInputSlot = (slotName, targetSlotName) => {
3412
3412
  return slotEle;
3413
3413
  };
3414
3414
 
3415
- const createExternalInputEle = (targetSlotName, autocompleteType) => {
3415
+ const createExternalInputEle = (targetSlotName, type, autocompleteType) => {
3416
3416
  const inputEle = document.createElement('input');
3417
3417
 
3418
3418
  inputEle.setAttribute('slot', targetSlotName);
3419
- inputEle.setAttribute('type', 'password');
3419
+ inputEle.setAttribute('type', type);
3420
3420
  inputEle.setAttribute('data-hidden-input', 'true');
3421
3421
  inputEle.setAttribute('autocomplete', autocompleteType);
3422
3422
 
3423
3423
  return inputEle;
3424
3424
  };
3425
3425
 
3426
- const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
3426
+ const applyExternalInputStyles = (sourceInputEle, targetInputEle, customStyle) => {
3427
3427
  const computedStyle = getComputedStyle(sourceInputEle);
3428
3428
  const height = computedStyle.getPropertyValue('height');
3429
3429
  const paddingLeft = computedStyle.getPropertyValue('padding-left');
@@ -3439,7 +3439,6 @@ const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
3439
3439
  targetInputEle.style = `
3440
3440
  all: unset !important;
3441
3441
  position: absolute !important;
3442
- width: calc(100% - 3em) !important;
3443
3442
  background-color: transparent !important;
3444
3443
  color: ${valueColor} !important;
3445
3444
  height: ${height} !important;
@@ -3449,6 +3448,7 @@ const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
3449
3448
  font-family: ${fontFamily} !important;
3450
3449
  letter-spacing: ${letterSpacing} !important;
3451
3450
  caret-color: ${caretColor} !important;
3451
+ ${customStyle || ''}
3452
3452
  `;
3453
3453
  };
3454
3454
 
@@ -3473,11 +3473,23 @@ const customMixin$9 = (superclass) =>
3473
3473
  this.baseElement.appendChild(externalInputSlot);
3474
3474
 
3475
3475
  // create external input
3476
- const externalInput = createExternalInputEle('external-input', this.getAutocompleteType());
3476
+ const externalInput = createExternalInputEle(
3477
+ 'external-input',
3478
+ 'password',
3479
+ this.getAutocompleteType()
3480
+ );
3481
+
3482
+ this.handlePasswordVisibility(externalInput);
3477
3483
 
3478
3484
  // apply original input's styles to external input
3479
3485
  setTimeout(() => {
3480
- applyExternalInputStyles(origInput, externalInput);
3486
+ applyExternalInputStyles(
3487
+ origInput,
3488
+ externalInput,
3489
+ `
3490
+ width: calc(100% - 3em) !important;
3491
+ `
3492
+ );
3481
3493
  });
3482
3494
 
3483
3495
  // set external input events
@@ -3485,6 +3497,7 @@ const customMixin$9 = (superclass) =>
3485
3497
 
3486
3498
  // sync input stateful attributes: `type` (for visibility state change) and `readonly`
3487
3499
  syncAttrs(origInput, externalInput, { includeAttrs: ['type', 'readonly'] });
3500
+ syncAttrs(this, externalInput, { includeAttrs: ['focused'] });
3488
3501
 
3489
3502
  origInput.addEventListener('focus', (e) => {
3490
3503
  e.preventDefault();
@@ -3502,6 +3515,59 @@ const customMixin$9 = (superclass) =>
3502
3515
  this.appendChild(externalInput);
3503
3516
  }
3504
3517
 
3518
+ // override vaadin's password visibility toggle.
3519
+ // we need this override in order to to resolve the external input `focus` race condition,
3520
+ // which is caused due to the focus sync between the two inputs.
3521
+ handlePasswordVisibility(externalInput) {
3522
+ // disable vaadin's `__boundRevealButtonMouseDown` mouse-down event lisetener
3523
+ const origBoundRevealButtonMouseDown = this.baseElement.__boundRevealButtonMouseDown;
3524
+ this.baseElement
3525
+ .querySelector('vaadin-password-field-button')
3526
+ .removeEventListener('mousedown', origBoundRevealButtonMouseDown);
3527
+
3528
+ // disable vaadin's `_passwordVisibleChanged` observer
3529
+ this.baseElement._passwordVisibleChanged = () => {};
3530
+
3531
+ // override vaadin's `_togglePasswordVisibility`
3532
+ this.baseElement._togglePasswordVisibility = () => {
3533
+ const currVisibility = externalInput.getAttribute('type');
3534
+ if (currVisibility === 'password') {
3535
+ this.showPasswordVisibility(externalInput);
3536
+ } else {
3537
+ this.hidePasswordVisibility(externalInput);
3538
+ }
3539
+ };
3540
+
3541
+ // on component blur, if password is revealed - hide it
3542
+ // this behaves differently from vaadin's focus handling, and checks if the blur takes the component out of focus
3543
+ // (which menas the click was made outside the component) or if the blur was called due to clicking the Reveal Button
3544
+ // and then focusing in the input again
3545
+ this.addEventListener('blur', () => {
3546
+ setTimeout(() => {
3547
+ const isHiddenAndFocused =
3548
+ externalInput.getAttribute('type') !== 'password' &&
3549
+ externalInput.getAttribute('focused') !== 'true';
3550
+ if (isHiddenAndFocused) {
3551
+ this.hidePasswordVisibility(externalInput);
3552
+ }
3553
+ });
3554
+ });
3555
+ }
3556
+
3557
+ hidePasswordVisibility(input) {
3558
+ // handle input element's type
3559
+ input.setAttribute('type', 'password');
3560
+ // handle vaadin's `password-visible` attribute
3561
+ this.setAttribute('password-visible', 'false');
3562
+ }
3563
+
3564
+ showPasswordVisibility(input) {
3565
+ // handle input element's type
3566
+ input.setAttribute('type', 'text');
3567
+ // handle vaadin's `password-visible` attribute
3568
+ this.setAttribute('password-visible', 'true');
3569
+ }
3570
+
3505
3571
  getAutocompleteType() {
3506
3572
  return this.getAttribute('autocomplete') || 'current-password';
3507
3573
  }
@@ -3760,9 +3826,68 @@ const customMixin$8 = (superclass) =>
3760
3826
  class EmailFieldMixinClass extends superclass {
3761
3827
  init() {
3762
3828
  super.init?.();
3829
+
3763
3830
  this.baseElement.setAttribute('pattern', '^[\\w\\.\\%\\+\\-]+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$');
3831
+
3832
+ this.handleExternalInput();
3833
+ }
3834
+
3835
+ handleExternalInput() {
3836
+ // reset vaadin's checkValidity
3837
+ this.baseElement.checkValidity = () => {};
3838
+
3839
+ // set safety attribute `external-input`
3840
+ this.setAttribute('external-input', 'true');
3841
+
3842
+ // use original input element as reference
3843
+ const origInput = this.baseElement.querySelector('input');
3844
+
3845
+ // create external slot
3846
+ const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
3847
+ // append external slot to base element
3848
+ this.baseElement.appendChild(externalInputSlot);
3849
+
3850
+ const externalInput = createExternalInputEle(
3851
+ 'external-input',
3852
+ 'text',
3853
+ this.getAutocompleteType()
3854
+ );
3855
+
3856
+ // apply original input's styles to external input
3857
+ setTimeout(() => {
3858
+ applyExternalInputStyles(origInput, externalInput);
3859
+ });
3860
+
3861
+ // set external input events
3862
+ this.handleExternalInputEvents(externalInput);
3863
+
3864
+ syncAttrs(origInput, externalInput, { includeAttrs: ['disabled', 'readonly', 'pattern'] });
3865
+
3866
+ // append external input to component's DOM
3867
+ this.appendChild(externalInput);
3868
+ }
3869
+
3870
+ getAutocompleteType() {
3871
+ return this.getAttribute('autocomplete') || 'username';
3872
+ }
3873
+
3874
+ handleExternalInputEvents(inputEle) {
3875
+ // sync value of insible input back to original input
3876
+ inputEle.addEventListener('input', (e) => {
3877
+ this.value = e.target.value;
3878
+ });
3879
+
3880
+ // sync `focused` attribute on host when focusing on external input
3881
+ inputEle.addEventListener('focus', () => {
3882
+ this.setAttribute('focused', 'true');
3883
+ });
3884
+
3885
+ inputEle.addEventListener('blur', () => {
3886
+ this.removeAttribute('focused');
3887
+ });
3764
3888
  }
3765
3889
  };
3890
+
3766
3891
  const EmailFieldClass = compose(
3767
3892
  createStyleMixin({
3768
3893
  mappings: textFieldMappings,