@descope/web-components-ui 1.0.320 → 1.0.322

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
@@ -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
  }