@descope/web-components-ui 1.0.313 → 1.0.314

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
@@ -763,8 +763,13 @@ const errorAttributes = {
763
763
  tooShort: 'data-errormessage-pattern-mismatch-too-short',
764
764
  tooLong: 'data-errormessage-pattern-mismatch-too-long',
765
765
  };
766
+
767
+ const validationTargetSymbol = Symbol('validationTarget');
768
+
766
769
  const inputValidationMixin = (superclass) =>
767
770
  class InputValidationMixinClass extends superclass {
771
+ #validationTarget = validationTargetSymbol;
772
+
768
773
  static get observedAttributes() {
769
774
  return [...(superclass.observedAttributes || []), ...observedAttributes$6];
770
775
  }
@@ -881,7 +886,13 @@ const inputValidationMixin = (superclass) =>
881
886
  }
882
887
 
883
888
  get validationTarget() {
884
- return this.inputElement;
889
+ return this.#validationTarget === validationTargetSymbol
890
+ ? this.inputElement
891
+ : this.#validationTarget;
892
+ }
893
+
894
+ set validationTarget(val) {
895
+ this.#validationTarget = val;
885
896
  }
886
897
 
887
898
  setCustomValidity(errorMessage) {
@@ -2539,7 +2550,7 @@ var textFieldMappings = {
2539
2550
 
2540
2551
  const componentName$K = getComponentName('email-field');
2541
2552
 
2542
- const customMixin$8 = (superclass) =>
2553
+ const customMixin$9 = (superclass) =>
2543
2554
  class EmailFieldMixinClass extends superclass {
2544
2555
  init() {
2545
2556
  super.init?.();
@@ -2553,7 +2564,7 @@ const EmailFieldClass = compose(
2553
2564
  draggableMixin,
2554
2565
  composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
2555
2566
  componentNameValidationMixin,
2556
- customMixin$8
2567
+ customMixin$9
2557
2568
  )(
2558
2569
  createProxy({
2559
2570
  slots: ['', 'suffix'],
@@ -3012,7 +3023,7 @@ const componentName$D = getComponentName('text-field');
3012
3023
 
3013
3024
  const observedAttrs = ['type'];
3014
3025
 
3015
- const customMixin$7 = (superclass) =>
3026
+ const customMixin$8 = (superclass) =>
3016
3027
  class TextFieldClass extends superclass {
3017
3028
  static get observedAttributes() {
3018
3029
  return observedAttrs.concat(superclass.observedAttributes || []);
@@ -3064,7 +3075,7 @@ const TextFieldClass = compose(
3064
3075
  draggableMixin,
3065
3076
  composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
3066
3077
  componentNameValidationMixin,
3067
- customMixin$7
3078
+ customMixin$8
3068
3079
  )(
3069
3080
  createProxy({
3070
3081
  slots: ['prefix', 'suffix'],
@@ -3091,7 +3102,7 @@ const componentName$C = getComponentName('passcode');
3091
3102
 
3092
3103
  const observedAttributes$4 = ['digits'];
3093
3104
 
3094
- const customMixin$6 = (superclass) =>
3105
+ const customMixin$7 = (superclass) =>
3095
3106
  class PasscodeMixinClass extends superclass {
3096
3107
  static get observedAttributes() {
3097
3108
  return observedAttributes$4.concat(superclass.observedAttributes || []);
@@ -3187,7 +3198,7 @@ const PasscodeClass = compose(
3187
3198
  draggableMixin,
3188
3199
  composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
3189
3200
  componentNameValidationMixin,
3190
- customMixin$6
3201
+ customMixin$7
3191
3202
  )(
3192
3203
  createProxy({
3193
3204
  slots: [],
@@ -3283,32 +3294,165 @@ const passwordDraggableMixin = (superclass) =>
3283
3294
  // there is an issue in Chrome that input field with type password cannot be D&D
3284
3295
  // so in case the input is draggable & readonly, we are changing the input type to "text" before dragging
3285
3296
  // and return the original type when done
3286
- this.addEventListener('mousedown', (e) => {
3297
+ super.init?.();
3298
+
3299
+ const ele = this.querySelector('input');
3300
+
3301
+ ele?.addEventListener('mousedown', (e) => {
3287
3302
  if (this.isDraggable && this.isReadOnly) {
3288
- const inputEle = this.baseElement.querySelector('input');
3289
- const prevType = inputEle.getAttribute('type');
3303
+ ele.setAttribute('inert', 'true');
3290
3304
 
3305
+ const inputEle = e.target;
3306
+ const prevType = inputEle.getAttribute('type');
3291
3307
  inputEle.setAttribute('type', 'text');
3292
- setTimeout(() => inputEle.focus());
3308
+ setTimeout(() => {
3309
+ inputEle.focus();
3310
+ });
3293
3311
 
3294
3312
  const onComplete = (_) => {
3295
3313
  inputEle.setAttribute('type', prevType);
3296
-
3297
- e.target.removeEventListener('mouseup', onComplete);
3298
- e.target.removeEventListener('dragend', onComplete);
3314
+ ele.removeAttribute('inert');
3315
+ this.removeEventListener('mouseup', onComplete);
3316
+ this.removeEventListener('dragend', onComplete);
3299
3317
  };
3300
3318
 
3301
- e.target.addEventListener('mouseup', onComplete, { once: true });
3302
- e.target.addEventListener('dragend', onComplete, { once: true });
3319
+ this.addEventListener('dragend', onComplete, { once: true });
3320
+ this.addEventListener('mouseup', onComplete, { once: true });
3303
3321
  }
3304
3322
  });
3305
-
3306
- super.init?.();
3307
3323
  }
3308
3324
  };
3309
3325
 
3326
+ // since on load we can only sample the color of the placeholder,
3327
+ // we need to temporarily populate the input in order to sample the value color
3328
+ const getValueColor = (ele, computedStyle) => {
3329
+ // eslint-disable-next-line no-param-reassign
3330
+ ele.value = '_';
3331
+
3332
+ const valueColor = computedStyle.getPropertyValue('color');
3333
+
3334
+ // eslint-disable-next-line no-param-reassign
3335
+ ele.value = '';
3336
+
3337
+ return valueColor;
3338
+ };
3339
+
3340
+ const createExternalInputSlot = (slotName, targetSlotName) => {
3341
+ const slotEle = document.createElement('slot');
3342
+
3343
+ slotEle.setAttribute('name', slotName);
3344
+ slotEle.setAttribute('slot', targetSlotName);
3345
+
3346
+ return slotEle;
3347
+ };
3348
+
3349
+ const createExternalInputEle = (targetSlotName, autocompleteType) => {
3350
+ const inputEle = document.createElement('input');
3351
+
3352
+ inputEle.setAttribute('slot', targetSlotName);
3353
+ inputEle.setAttribute('type', 'password');
3354
+ inputEle.setAttribute('data-hidden-input', 'true');
3355
+ inputEle.setAttribute('autocomplete', autocompleteType);
3356
+
3357
+ return inputEle;
3358
+ };
3359
+
3360
+ const applyExternalInputStyles = (sourceInputEle, targetInputEle) => {
3361
+ const computedStyle = getComputedStyle(sourceInputEle);
3362
+ const height = computedStyle.getPropertyValue('height');
3363
+ const paddingLeft = computedStyle.getPropertyValue('padding-left');
3364
+ const paddingRight = computedStyle.getPropertyValue('padding-right');
3365
+ const fontSize = computedStyle.getPropertyValue('font-size');
3366
+ const fontFamily = computedStyle.getPropertyValue('font-family');
3367
+ const letterSpacing = computedStyle.getPropertyValue('letter-spacing');
3368
+ const caretColor = computedStyle.getPropertyValue('caret-color');
3369
+ const valueColor = getValueColor(sourceInputEle, computedStyle);
3370
+
3371
+ // set external input style (and lock it with `all: unset` and `!important` all around)
3372
+ // eslint-disable-next-line no-param-reassign
3373
+ targetInputEle.style = `
3374
+ all: unset !important;
3375
+ position: absolute !important;
3376
+ width: calc(100% - 3em) !important;
3377
+ background-color: transparent !important;
3378
+ color: ${valueColor} !important;
3379
+ height: ${height} !important;
3380
+ left: ${paddingLeft} !important;
3381
+ right: ${paddingRight} !important;
3382
+ font-size: ${fontSize} !important;
3383
+ font-family: ${fontFamily} !important;
3384
+ letter-spacing: ${letterSpacing} !important;
3385
+ caret-color: ${caretColor} !important;
3386
+ `;
3387
+ };
3388
+
3310
3389
  const componentName$B = getComponentName('password');
3311
3390
 
3391
+ const customMixin$6 = (superclass) =>
3392
+ class PasswordFieldMixinClass extends superclass {
3393
+ init() {
3394
+ super.init?.();
3395
+
3396
+ // reset vaadin's checkValidity
3397
+ this.baseElement.checkValidity = () => {};
3398
+ // set safety attribute `external-input`
3399
+ this.setAttribute('external-input', 'true');
3400
+
3401
+ // use original input element as reference
3402
+ const origInput = this.baseElement.querySelector('input');
3403
+
3404
+ // create external slot
3405
+ const externalInputSlot = createExternalInputSlot('external-input', 'suffix');
3406
+ // append external slot to base element
3407
+ this.baseElement.appendChild(externalInputSlot);
3408
+
3409
+ // create external input
3410
+ const externalInput = createExternalInputEle('external-input', this.getAutocompleteType());
3411
+
3412
+ // apply original input's styles to external input
3413
+ setTimeout(() => {
3414
+ applyExternalInputStyles(origInput, externalInput);
3415
+ });
3416
+
3417
+ // set external input events
3418
+ this.handleExternalInputEvents(externalInput);
3419
+
3420
+ // sync input stateful attributes: `type` (for visibility state change) and `readonly`
3421
+ syncAttrs(origInput, externalInput, { includeAttrs: ['type', 'readonly'] });
3422
+
3423
+ origInput.addEventListener('focus', (e) => {
3424
+ e.preventDefault();
3425
+ if (e.isTrusted) {
3426
+ externalInput.focus();
3427
+ }
3428
+ });
3429
+
3430
+ this.addEventListener('focus', (e) => {
3431
+ e.preventDefault();
3432
+ this.focus();
3433
+ });
3434
+
3435
+ // append external input to component's DOM
3436
+ this.appendChild(externalInput);
3437
+ }
3438
+
3439
+ getAutocompleteType() {
3440
+ return this.getAttribute('autocomplete') || 'current-password';
3441
+ }
3442
+
3443
+ handleExternalInputEvents(inputEle) {
3444
+ // sync value of insible input back to original input
3445
+ inputEle.addEventListener('input', (e) => {
3446
+ this.value = e.target.value;
3447
+ });
3448
+
3449
+ // sync `focused` attribute on host when focusing on external input
3450
+ inputEle.addEventListener('focus', () => {
3451
+ this.setAttribute('focused', 'true');
3452
+ });
3453
+ }
3454
+ };
3455
+
3312
3456
  const {
3313
3457
  host: host$f,
3314
3458
  inputField: inputField$5,
@@ -3324,9 +3468,9 @@ const {
3324
3468
  host: { selector: () => ':host' },
3325
3469
  inputField: { selector: '::part(input-field)' },
3326
3470
  inputElement: { selector: '> input' },
3327
- inputElementPlaceholder: { selector: '> input:placeholder-shown' },
3328
- revealButtonContainer: { selector: () => '::part(reveal-button)' },
3329
- revealButtonIcon: { selector: () => '::part(reveal-button)::before' },
3471
+ inputElementPlaceholder: { selector: () => ':host input:placeholder-shown' },
3472
+ revealButtonContainer: { selector: '::part(reveal-button)' },
3473
+ revealButtonIcon: { selector: '::part(reveal-button)::before' },
3330
3474
  label: { selector: '::part(label)' },
3331
3475
  requiredIndicator: { selector: '[required]::part(required-indicator)::after' },
3332
3476
  helperText: { selector: '::part(helper-text)' },
@@ -3365,8 +3509,14 @@ const PasswordClass = compose(
3365
3509
  labelRequiredIndicator: { ...requiredIndicator$7, property: 'content' },
3366
3510
  errorMessageTextColor: { ...errorMessage$8, property: 'color' },
3367
3511
 
3368
- inputValueTextColor: { ...inputElement$2, property: 'color' },
3369
- inputPlaceholderTextColor: { ...inputElementPlaceholder, property: 'color' },
3512
+ inputPlaceholderTextColor: [
3513
+ { ...inputElementPlaceholder, property: 'color' },
3514
+ { selector: () => ':host ::slotted(input:placeholder-shown)', property: 'color' },
3515
+ ],
3516
+ inputValueTextColor: [
3517
+ { ...inputElement$2, property: 'color' },
3518
+ { selector: () => ':host ::slotted(input)', property: 'color' },
3519
+ ],
3370
3520
 
3371
3521
  revealButtonOffset: [
3372
3522
  { ...revealButtonContainer, property: 'margin-right' },
@@ -3379,7 +3529,8 @@ const PasswordClass = compose(
3379
3529
  draggableMixin,
3380
3530
  composedProxyInputMixin({ proxyProps: ['value', 'selectionStart'] }),
3381
3531
  componentNameValidationMixin,
3382
- passwordDraggableMixin
3532
+ passwordDraggableMixin,
3533
+ customMixin$6
3383
3534
  )(
3384
3535
  createProxy({
3385
3536
  slots: ['', 'suffix'],
@@ -3390,6 +3541,7 @@ const PasswordClass = compose(
3390
3541
  max-width: 100%;
3391
3542
  min-width: 10em;
3392
3543
  box-sizing: border-box;
3544
+ position: relative;
3393
3545
  }
3394
3546
  ${useHostExternalPadding(PasswordClass.cssVarList)}
3395
3547
  ${resetInputCursor('vaadin-password-field')}
@@ -3401,7 +3553,9 @@ const PasswordClass = compose(
3401
3553
  padding: 0;
3402
3554
  }
3403
3555
  vaadin-password-field > input {
3556
+ -webkit-mask-image: none;
3404
3557
  box-sizing: border-box;
3558
+ opacity: 1;
3405
3559
  }
3406
3560
  vaadin-password-field::part(input-field) {
3407
3561
  box-sizing: border-box;
@@ -3410,12 +3564,11 @@ const PasswordClass = compose(
3410
3564
  vaadin-password-field[focus-ring]::part(input-field) {
3411
3565
  box-shadow: none;
3412
3566
  }
3413
- vaadin-password-field > input {
3567
+ :host ::slotted(input) {
3414
3568
  min-height: 0;
3415
- -webkit-mask-image: none;
3416
- }
3417
- vaadin-password-field[readonly] > input:placeholder-shown {
3418
- opacity: 1;
3569
+ }
3570
+ :host([readonly]) ::slotted(input:placeholder-shown) {
3571
+ opacity: 0;
3419
3572
  }
3420
3573
  vaadin-password-field::before {
3421
3574
  height: initial;
@@ -3426,11 +3579,9 @@ const PasswordClass = compose(
3426
3579
  vaadin-password-field-button {
3427
3580
  cursor: pointer;
3428
3581
  }
3429
-
3430
- [readonly] vaadin-password-field-button {
3582
+ :host([readonly]) vaadin-password-field-button {
3431
3583
  pointer-events: none;
3432
3584
  }
3433
-
3434
3585
  vaadin-password-field-button[focus-ring] {
3435
3586
  box-shadow: 0 0 0 2px var(${PasswordClass.cssVarList.inputOutlineColor});
3436
3587
  }
@@ -6354,13 +6505,24 @@ const customMixin$3 = (superclass) =>
6354
6505
  name="new-password"
6355
6506
  tabindex="-1"
6356
6507
  slot="input"
6357
- ></${componentName$s}>
6508
+ >
6509
+ </${componentName$s}>
6358
6510
  `;
6359
6511
 
6512
+ this.setAttribute('external-input', 'true');
6513
+
6360
6514
  this.baseElement.appendChild(template.content.cloneNode(true));
6361
6515
 
6362
6516
  this.inputElement = this.shadowRoot.querySelector(componentName$s);
6363
6517
 
6518
+ // get descope input components
6519
+ this.passwordInput = this.inputElement.querySelector('[data-id="password"]');
6520
+ this.confirmInput = this.inputElement.querySelector('[data-id="confirm"]');
6521
+
6522
+ // create slots for external password input
6523
+ this.createExternalInput(this.passwordInput, 'external-password-input');
6524
+ this.createExternalInput(this.confirmInput, 'external-confirm-input');
6525
+
6364
6526
  forwardAttrs(this, this.inputElement, {
6365
6527
  includeAttrs: [
6366
6528
  'password-label',
@@ -6383,6 +6545,20 @@ const customMixin$3 = (superclass) =>
6383
6545
  ],
6384
6546
  });
6385
6547
  }
6548
+
6549
+ createExternalInput(node, slotName) {
6550
+ const externalInput = node.querySelector('input');
6551
+ const slotEle = document.createElement('slot');
6552
+ const targetSlot = externalInput.getAttribute('slot');
6553
+ slotEle.setAttribute('name', slotName);
6554
+ slotEle.setAttribute('slot', targetSlot);
6555
+ node.appendChild(slotEle);
6556
+
6557
+ // move external input
6558
+ externalInput.setAttribute('slot', slotName);
6559
+ externalInput.setAttribute('data-hidden-input', 'true');
6560
+ this.appendChild(externalInput);
6561
+ }
6386
6562
  };
6387
6563
 
6388
6564
  const {
@@ -6470,6 +6646,7 @@ const NewPasswordClass = compose(
6470
6646
  padding: 0;
6471
6647
  }
6472
6648
  descope-new-password-internal > .wrapper {
6649
+ -webkit-mask-image: none;
6473
6650
  width: 100%;
6474
6651
  height: 100%;
6475
6652
  display: flex;
@@ -6506,6 +6683,7 @@ const passwordInputAttrs = ['password-label', 'password-placeholder'];
6506
6683
  const confirmInputAttrs = ['confirm-label', 'confirm-placeholder'];
6507
6684
  const policyPanelAttrs = ['has-validation'];
6508
6685
  const commonAttrs = [
6686
+ 'has-confirm',
6509
6687
  'disabled',
6510
6688
  'bordered',
6511
6689
  'size',
@@ -6528,7 +6706,7 @@ const BaseInputClass$4 = createBaseInputClass({ componentName: componentName$s,
6528
6706
 
6529
6707
  class NewPasswordInternal extends BaseInputClass$4 {
6530
6708
  static get observedAttributes() {
6531
- return ['has-confirm'].concat(BaseInputClass$4.observedAttributes || [], inputRelatedAttrs);
6709
+ return [].concat(BaseInputClass$4.observedAttributes || [], inputRelatedAttrs);
6532
6710
  }
6533
6711
 
6534
6712
  constructor() {
@@ -6554,6 +6732,14 @@ class NewPasswordInternal extends BaseInputClass$4 {
6554
6732
  return this.getAttribute('has-confirm') === 'true';
6555
6733
  }
6556
6734
 
6735
+ onHasConfirmChange(hasConfirm) {
6736
+ this.confirmInput.style.display = hasConfirm ? '' : 'none';
6737
+ }
6738
+
6739
+ onHasValidationChange(hasValidation) {
6740
+ this.policyPanel.style.display = hasValidation ? '' : 'none';
6741
+ }
6742
+
6557
6743
  get hasValidation() {
6558
6744
  return this.getAttribute('has-validation') === 'true';
6559
6745
  }
@@ -6592,20 +6778,15 @@ class NewPasswordInternal extends BaseInputClass$4 {
6592
6778
  this.renderInputs(this.hasConfirm, this.hasValidation);
6593
6779
  }
6594
6780
 
6595
- renderInputs(shouldRenderConfirm, shouldRenderValidation) {
6596
- let template = `
6781
+ renderInputs() {
6782
+ const template = `
6597
6783
  <div>
6598
- <descope-password data-id="password"></descope-password>
6599
- <descope-policy-validation class="${
6600
- shouldRenderValidation ? 'hidden' : ''
6601
- }"></descope-policy-validation>
6784
+ <descope-password autocomplete="new-password" data-id="password"></descope-password>
6785
+ <descope-policy-validation></descope-policy-validation>
6602
6786
  </div>
6787
+ <descope-password autocomplete="new-password" data-id="confirm"></descope-password>
6603
6788
  `;
6604
6789
 
6605
- if (shouldRenderConfirm) {
6606
- template += `<descope-password data-id="confirm"></descope-password>`;
6607
- }
6608
-
6609
6790
  this.wrapperEle.innerHTML = template;
6610
6791
 
6611
6792
  this.passwordInput = this.querySelector('[data-id="password"]');
@@ -6616,12 +6797,7 @@ class NewPasswordInternal extends BaseInputClass$4 {
6616
6797
 
6617
6798
  this.initInputs();
6618
6799
 
6619
- // we are calling attributeChangedCallback with all the input related attributes
6620
- // in order to set it on the newly generated input
6621
- [...passwordInputAttrs, ...confirmInputAttrs, ...commonAttrs].forEach((attr) => {
6622
- this.attributeChangedCallback(attr, null, this.getAttribute(attr));
6623
- });
6624
-
6800
+ // sync input value to policy validation panel
6625
6801
  this.passwordInput.addEventListener('input', (e) => {
6626
6802
  this.policyPanel.setAttribute('value', e.target.value);
6627
6803
  });
@@ -6697,22 +6873,14 @@ class NewPasswordInternal extends BaseInputClass$4 {
6697
6873
  value === null ? ele?.removeAttribute(name) : ele?.setAttribute(name, value);
6698
6874
  }
6699
6875
 
6700
- hidePolicy() {
6701
- this.policyPanel.classList.add('hidden');
6702
- }
6703
-
6704
- showPolicy() {
6705
- this.policyPanel.classList.remove('hidden');
6706
- }
6707
-
6708
6876
  attributeChangedCallback(attrName, oldValue, newValue) {
6709
6877
  super.attributeChangedCallback?.(attrName, oldValue, newValue);
6710
6878
 
6711
6879
  if (oldValue !== newValue) {
6712
6880
  if (attrName === 'has-validation') {
6713
- this.renderInputs(this.hasConfirm, newValue === 'true');
6881
+ this.onHasValidationChange(newValue === 'true');
6714
6882
  } else if (attrName === 'has-confirm') {
6715
- this.renderInputs(newValue !== null && newValue !== 'false', this.hasValidation);
6883
+ this.onHasConfirmChange(newValue === 'true');
6716
6884
  } else if (commonAttrs.includes(attrName)) {
6717
6885
  this.inputs.forEach((input) => this.toggleBooleanAttribute(input, attrName, newValue));
6718
6886
  } else if (passwordInputAttrs.includes(attrName)) {
@@ -6728,9 +6896,6 @@ class NewPasswordInternal extends BaseInputClass$4 {
6728
6896
  newValue
6729
6897
  );
6730
6898
  }
6731
- if (attrName === 'has-validation') {
6732
- newValue === 'true' ? this.showPolicy() : this.hidePolicy();
6733
- }
6734
6899
  }
6735
6900
  }
6736
6901
  }