@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.
package/dist/index.esm.js CHANGED
@@ -2549,15 +2549,137 @@ var textFieldMappings = {
2549
2549
  ],
2550
2550
  };
2551
2551
 
2552
+ // since on load we can only sample the color of the placeholder,
2553
+ // we need to temporarily populate the input in order to sample the value color
2554
+ const getValueColor = (ele, computedStyle) => {
2555
+ // eslint-disable-next-line no-param-reassign
2556
+ ele.value = '_';
2557
+
2558
+ const valueColor = computedStyle.getPropertyValue('color');
2559
+
2560
+ // eslint-disable-next-line no-param-reassign
2561
+ ele.value = '';
2562
+
2563
+ return valueColor;
2564
+ };
2565
+
2566
+ const createExternalInputSlot = (slotName, targetSlotName) => {
2567
+ const slotEle = document.createElement('slot');
2568
+
2569
+ slotEle.setAttribute('name', slotName);
2570
+ slotEle.setAttribute('slot', targetSlotName);
2571
+
2572
+ return slotEle;
2573
+ };
2574
+
2575
+ const createExternalInputEle = (targetSlotName, type, autocompleteType) => {
2576
+ const inputEle = document.createElement('input');
2577
+
2578
+ inputEle.setAttribute('slot', targetSlotName);
2579
+ inputEle.setAttribute('type', type);
2580
+ inputEle.setAttribute('data-hidden-input', 'true');
2581
+ inputEle.setAttribute('autocomplete', autocompleteType);
2582
+
2583
+ return inputEle;
2584
+ };
2585
+
2586
+ const applyExternalInputStyles = (sourceInputEle, targetInputEle, customStyle) => {
2587
+ const computedStyle = getComputedStyle(sourceInputEle);
2588
+ const height = computedStyle.getPropertyValue('height');
2589
+ const paddingLeft = computedStyle.getPropertyValue('padding-left');
2590
+ const paddingRight = computedStyle.getPropertyValue('padding-right');
2591
+ const fontSize = computedStyle.getPropertyValue('font-size');
2592
+ const fontFamily = computedStyle.getPropertyValue('font-family');
2593
+ const letterSpacing = computedStyle.getPropertyValue('letter-spacing');
2594
+ const caretColor = computedStyle.getPropertyValue('caret-color');
2595
+ const valueColor = getValueColor(sourceInputEle, computedStyle);
2596
+
2597
+ // set external input style (and lock it with `all: unset` and `!important` all around)
2598
+ // eslint-disable-next-line no-param-reassign
2599
+ targetInputEle.style = `
2600
+ all: unset !important;
2601
+ position: absolute !important;
2602
+ background-color: transparent !important;
2603
+ color: ${valueColor} !important;
2604
+ height: ${height} !important;
2605
+ left: ${paddingLeft} !important;
2606
+ right: ${paddingRight} !important;
2607
+ font-size: ${fontSize} !important;
2608
+ font-family: ${fontFamily} !important;
2609
+ letter-spacing: ${letterSpacing} !important;
2610
+ caret-color: ${caretColor} !important;
2611
+ ${customStyle || ''}
2612
+ `;
2613
+ };
2614
+
2552
2615
  const componentName$M = getComponentName('email-field');
2553
2616
 
2554
2617
  const customMixin$a = (superclass) =>
2555
2618
  class EmailFieldMixinClass extends superclass {
2556
2619
  init() {
2557
2620
  super.init?.();
2621
+
2558
2622
  this.baseElement.setAttribute('pattern', '^[\\w\\.\\%\\+\\-]+@[\\w\\.\\-]+\\.[A-Za-z]{2,}$');
2623
+
2624
+ this.handleExternalInput();
2625
+ }
2626
+
2627
+ handleExternalInput() {
2628
+ // reset vaadin's checkValidity
2629
+ this.baseElement.checkValidity = () => {};
2630
+
2631
+ // set safety attribute `external-input`
2632
+ this.setAttribute('external-input', 'true');
2633
+
2634
+ // use original input element as reference
2635
+ const origInput = this.baseElement.querySelector('input');
2636
+
2637
+ // create external slot
2638
+ const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
2639
+ // append external slot to base element
2640
+ this.baseElement.appendChild(externalInputSlot);
2641
+
2642
+ const externalInput = createExternalInputEle(
2643
+ 'external-input',
2644
+ 'text',
2645
+ this.getAutocompleteType()
2646
+ );
2647
+
2648
+ // apply original input's styles to external input
2649
+ setTimeout(() => {
2650
+ applyExternalInputStyles(origInput, externalInput);
2651
+ });
2652
+
2653
+ // set external input events
2654
+ this.handleExternalInputEvents(externalInput);
2655
+
2656
+ syncAttrs(origInput, externalInput, { includeAttrs: ['disabled', 'readonly', 'pattern'] });
2657
+
2658
+ // append external input to component's DOM
2659
+ this.appendChild(externalInput);
2660
+ }
2661
+
2662
+ getAutocompleteType() {
2663
+ return this.getAttribute('autocomplete') || 'username';
2664
+ }
2665
+
2666
+ handleExternalInputEvents(inputEle) {
2667
+ // sync value of insible input back to original input
2668
+ inputEle.addEventListener('input', (e) => {
2669
+ this.value = e.target.value;
2670
+ });
2671
+
2672
+ // sync `focused` attribute on host when focusing on external input
2673
+ inputEle.addEventListener('focus', () => {
2674
+ this.setAttribute('focused', 'true');
2675
+ });
2676
+
2677
+ inputEle.addEventListener('blur', () => {
2678
+ this.removeAttribute('focused');
2679
+ });
2559
2680
  }
2560
2681
  };
2682
+
2561
2683
  const EmailFieldClass = compose(
2562
2684
  createStyleMixin({
2563
2685
  mappings: textFieldMappings,
@@ -3327,69 +3449,6 @@ const passwordDraggableMixin = (superclass) =>
3327
3449
  }
3328
3450
  };
3329
3451
 
3330
- // since on load we can only sample the color of the placeholder,
3331
- // we need to temporarily populate the input in order to sample the value color
3332
- const getValueColor = (ele, computedStyle) => {
3333
- // eslint-disable-next-line no-param-reassign
3334
- ele.value = '_';
3335
-
3336
- const valueColor = computedStyle.getPropertyValue('color');
3337
-
3338
- // eslint-disable-next-line no-param-reassign
3339
- ele.value = '';
3340
-
3341
- return valueColor;
3342
- };
3343
-
3344
- const createExternalInputSlot = (slotName, targetSlotName) => {
3345
- const slotEle = document.createElement('slot');
3346
-
3347
- slotEle.setAttribute('name', slotName);
3348
- slotEle.setAttribute('slot', targetSlotName);
3349
-
3350
- return slotEle;
3351
- };
3352
-
3353
- const createExternalInputEle = (targetSlotName, autocompleteType) => {
3354
- const inputEle = document.createElement('input');
3355
-
3356
- inputEle.setAttribute('slot', targetSlotName);
3357
- inputEle.setAttribute('type', 'password');
3358
- inputEle.setAttribute('data-hidden-input', 'true');
3359
- inputEle.setAttribute('autocomplete', autocompleteType);
3360
-
3361
- return inputEle;
3362
- };
3363
-
3364
- const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
3365
- const computedStyle = getComputedStyle(sourceInputEle);
3366
- const height = computedStyle.getPropertyValue('height');
3367
- const paddingLeft = computedStyle.getPropertyValue('padding-left');
3368
- const paddingRight = computedStyle.getPropertyValue('padding-right');
3369
- const fontSize = computedStyle.getPropertyValue('font-size');
3370
- const fontFamily = computedStyle.getPropertyValue('font-family');
3371
- const letterSpacing = computedStyle.getPropertyValue('letter-spacing');
3372
- const caretColor = computedStyle.getPropertyValue('caret-color');
3373
- const valueColor = getValueColor(sourceInputEle, computedStyle);
3374
-
3375
- // set external input style (and lock it with `all: unset` and `!important` all around)
3376
- // eslint-disable-next-line no-param-reassign
3377
- targetInputEle.style = `
3378
- all: unset !important;
3379
- position: absolute !important;
3380
- width: calc(100% - 3em) !important;
3381
- background-color: transparent !important;
3382
- color: ${valueColor} !important;
3383
- height: ${height} !important;
3384
- left: ${paddingLeft} !important;
3385
- right: ${paddingRight} !important;
3386
- font-size: ${fontSize} !important;
3387
- font-family: ${fontFamily} !important;
3388
- letter-spacing: ${letterSpacing} !important;
3389
- caret-color: ${caretColor} !important;
3390
- `;
3391
- };
3392
-
3393
3452
  const componentName$D = getComponentName('password');
3394
3453
 
3395
3454
  const customMixin$7 = (superclass) =>
@@ -3411,11 +3470,23 @@ const customMixin$7 = (superclass) =>
3411
3470
  this.baseElement.appendChild(externalInputSlot);
3412
3471
 
3413
3472
  // create external input
3414
- const externalInput = createExternalInputEle('external-input', this.getAutocompleteType());
3473
+ const externalInput = createExternalInputEle(
3474
+ 'external-input',
3475
+ 'password',
3476
+ this.getAutocompleteType()
3477
+ );
3478
+
3479
+ this.handlePasswordVisibility(externalInput);
3415
3480
 
3416
3481
  // apply original input's styles to external input
3417
3482
  setTimeout(() => {
3418
- applyExternalInputStyles(origInput, externalInput);
3483
+ applyExternalInputStyles(
3484
+ origInput,
3485
+ externalInput,
3486
+ `
3487
+ width: calc(100% - 3em) !important;
3488
+ `
3489
+ );
3419
3490
  });
3420
3491
 
3421
3492
  // set external input events
@@ -3423,6 +3494,7 @@ const customMixin$7 = (superclass) =>
3423
3494
 
3424
3495
  // sync input stateful attributes: `type` (for visibility state change) and `readonly`
3425
3496
  syncAttrs(origInput, externalInput, { includeAttrs: ['type', 'readonly'] });
3497
+ syncAttrs(this, externalInput, { includeAttrs: ['focused'] });
3426
3498
 
3427
3499
  origInput.addEventListener('focus', (e) => {
3428
3500
  e.preventDefault();
@@ -3440,6 +3512,59 @@ const customMixin$7 = (superclass) =>
3440
3512
  this.appendChild(externalInput);
3441
3513
  }
3442
3514
 
3515
+ // override vaadin's password visibility toggle.
3516
+ // we need this override in order to to resolve the external input `focus` race condition,
3517
+ // which is caused due to the focus sync between the two inputs.
3518
+ handlePasswordVisibility(externalInput) {
3519
+ // disable vaadin's `__boundRevealButtonMouseDown` mouse-down event lisetener
3520
+ const origBoundRevealButtonMouseDown = this.baseElement.__boundRevealButtonMouseDown;
3521
+ this.baseElement
3522
+ .querySelector('vaadin-password-field-button')
3523
+ .removeEventListener('mousedown', origBoundRevealButtonMouseDown);
3524
+
3525
+ // disable vaadin's `_passwordVisibleChanged` observer
3526
+ this.baseElement._passwordVisibleChanged = () => {};
3527
+
3528
+ // override vaadin's `_togglePasswordVisibility`
3529
+ this.baseElement._togglePasswordVisibility = () => {
3530
+ const currVisibility = externalInput.getAttribute('type');
3531
+ if (currVisibility === 'password') {
3532
+ this.showPasswordVisibility(externalInput);
3533
+ } else {
3534
+ this.hidePasswordVisibility(externalInput);
3535
+ }
3536
+ };
3537
+
3538
+ // on component blur, if password is revealed - hide it
3539
+ // this behaves differently from vaadin's focus handling, and checks if the blur takes the component out of focus
3540
+ // (which menas the click was made outside the component) or if the blur was called due to clicking the Reveal Button
3541
+ // and then focusing in the input again
3542
+ this.addEventListener('blur', () => {
3543
+ setTimeout(() => {
3544
+ const isHiddenAndFocused =
3545
+ externalInput.getAttribute('type') !== 'password' &&
3546
+ externalInput.getAttribute('focused') !== 'true';
3547
+ if (isHiddenAndFocused) {
3548
+ this.hidePasswordVisibility(externalInput);
3549
+ }
3550
+ });
3551
+ });
3552
+ }
3553
+
3554
+ hidePasswordVisibility(input) {
3555
+ // handle input element's type
3556
+ input.setAttribute('type', 'password');
3557
+ // handle vaadin's `password-visible` attribute
3558
+ this.setAttribute('password-visible', 'false');
3559
+ }
3560
+
3561
+ showPasswordVisibility(input) {
3562
+ // handle input element's type
3563
+ input.setAttribute('type', 'text');
3564
+ // handle vaadin's `password-visible` attribute
3565
+ this.setAttribute('password-visible', 'true');
3566
+ }
3567
+
3443
3568
  getAutocompleteType() {
3444
3569
  return this.getAttribute('autocomplete') || 'current-password';
3445
3570
  }