@descope/web-components-ui 1.0.308 → 1.0.310

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.
Files changed (27) hide show
  1. package/dist/cjs/index.cjs.js +108 -48
  2. package/dist/cjs/index.cjs.js.map +1 -1
  3. package/dist/index.esm.js +113 -51
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/umd/4392.js +1 -1
  6. package/dist/umd/4978.js +1 -1
  7. package/dist/umd/DescopeDev.js +1 -1
  8. package/dist/umd/descope-email-field-index-js.js +4 -4
  9. package/dist/umd/descope-new-password-index-js.js +1 -1
  10. package/dist/umd/descope-number-field-index-js.js +1 -1
  11. package/dist/umd/descope-passcode-index-js.js +1 -1
  12. package/dist/umd/descope-recaptcha-index-js.js +1 -1
  13. package/dist/umd/descope-text-field-index-js.js +2 -2
  14. package/dist/umd/mapping-fields-descope-mappings-field-index-js.js +1 -1
  15. package/dist/umd/mapping-fields-descope-saml-group-mappings-index-js.js +1 -1
  16. package/dist/umd/phone-fields-descope-phone-field-descope-phone-field-internal-index-js.js +1 -1
  17. package/dist/umd/phone-fields-descope-phone-field-index-js.js +1 -1
  18. package/dist/umd/phone-fields-descope-phone-input-box-field-descope-phone-input-box-internal-index-js.js +2 -2
  19. package/dist/umd/phone-fields-descope-phone-input-box-field-index-js.js +1 -1
  20. package/package.json +2 -2
  21. package/src/components/descope-recaptcha/RecaptchaClass.js +50 -32
  22. package/src/components/descope-text-field/TextFieldClass.js +25 -0
  23. package/src/components/descope-text-field/textFieldMappings.js +21 -2
  24. package/src/components/phone-fields/descope-phone-field/descope-phone-field-internal/PhoneFieldInternal.js +2 -2
  25. package/src/components/phone-fields/descope-phone-input-box-field/descope-phone-input-box-internal/PhoneFieldInternalInputBox.js +3 -1
  26. package/src/mixins/componentsContextMixin.js +0 -4
  27. package/src/mixins/proxyInputMixin.js +1 -1
package/dist/index.esm.js CHANGED
@@ -545,21 +545,8 @@ const componentNameValidationMixin = (superclass) =>
545
545
  }
546
546
  };
547
547
 
548
- // create a dispatch event function that also calls to the onevent function in case it's set
549
- // usage example:
550
- // #dispatchSomething = createDispatchEvent.bind(this, 'something' { ...options })
551
- // this will dispatch a new event when called, but also call to "onsomething"
552
- function createDispatchEvent(eventName, options = {}) {
553
- const event = new Event(eventName, options);
554
-
555
- this[`on${eventName}`]?.(event); // in case we got an event callback as property
556
- this.dispatchEvent(event);
557
- }
558
-
559
548
  const componentsContextMixin = (superclass) =>
560
549
  class ComponentsContextMixinClass extends superclass {
561
- #dispatchComponentsContext = createDispatchEvent.bind(this, 'components-context');
562
-
563
550
  updateComponentsContext(componentsContext) {
564
551
  this.dispatchEvent(
565
552
  new CustomEvent('components-context', {
@@ -702,6 +689,17 @@ const createBaseClass = ({ componentName, baseSelector = '' }) => {
702
689
  )(DescopeBaseClass);
703
690
  };
704
691
 
692
+ // create a dispatch event function that also calls to the onevent function in case it's set
693
+ // usage example:
694
+ // #dispatchSomething = createDispatchEvent.bind(this, 'something' { ...options })
695
+ // this will dispatch a new event when called, but also call to "onsomething"
696
+ function createDispatchEvent(eventName, options = {}) {
697
+ const event = new Event(eventName, options);
698
+
699
+ this[`on${eventName}`]?.(event); // in case we got an event callback as property
700
+ this.dispatchEvent(event);
701
+ }
702
+
705
703
  const createProxy = ({
706
704
  componentName,
707
705
  wrappedEleName,
@@ -961,7 +959,7 @@ const getNestedInput = (ele) => {
961
959
  let nonSlotEle = ele;
962
960
  for (let i = 0; i < nestingLevel; i++) {
963
961
  [nonSlotEle] = nonSlotEle.assignedElements();
964
- if (nonSlotEle.localName !== 'slot') return nonSlotEle;
962
+ if (nonSlotEle?.localName !== 'slot') return nonSlotEle;
965
963
  }
966
964
  return undefined;
967
965
  };
@@ -2453,6 +2451,10 @@ const {
2453
2451
  errorMessage: errorMessage$a,
2454
2452
  disabledPlaceholder,
2455
2453
  inputDisabled,
2454
+ externalInput,
2455
+ externalInputDisabled,
2456
+ externalPlaceholder,
2457
+ externalDisabledPlaceholder,
2456
2458
  } = {
2457
2459
  host: { selector: () => ':host' },
2458
2460
  label: { selector: '::part(label)' },
@@ -2464,6 +2466,10 @@ const {
2464
2466
  inputDisabled: { selector: 'input:disabled' },
2465
2467
  helperText: { selector: '::part(helper-text)' },
2466
2468
  errorMessage: { selector: '::part(error-message)' },
2469
+ externalInput: { selector: () => '::slotted(input)' },
2470
+ externalInputDisabled: { selector: () => '::slotted(input:disabled)' },
2471
+ externalPlaceholder: { selector: () => '::slotted(input:placeholder-shown)' },
2472
+ externalDisabledPlaceholder: { selector: () => '::slotted(input:disabled::placeholder)' },
2467
2473
  };
2468
2474
 
2469
2475
  var textFieldMappings = {
@@ -2489,8 +2495,12 @@ var textFieldMappings = {
2489
2495
  inputValueTextColor: [
2490
2496
  { ...inputField$6, property: 'color' },
2491
2497
  { ...inputDisabled, property: '-webkit-text-fill-color' },
2498
+ { ...externalInputDisabled, property: '-webkit-text-fill-color' },
2499
+ ],
2500
+ inputCaretTextColor: [
2501
+ { ...input, property: 'color' },
2502
+ { ...externalInput, property: 'color' },
2492
2503
  ],
2493
- inputCaretTextColor: { ...input, property: 'color' },
2494
2504
 
2495
2505
  labelRequiredIndicator: { ...requiredIndicator$9, property: 'content' },
2496
2506
 
@@ -2503,6 +2513,8 @@ var textFieldMappings = {
2503
2513
  inputHorizontalPadding: [
2504
2514
  { ...input, property: 'padding-left' },
2505
2515
  { ...input, property: 'padding-right' },
2516
+ { ...externalInput, property: 'padding-left' },
2517
+ { ...externalInput, property: 'padding-right' },
2506
2518
  ],
2507
2519
 
2508
2520
  inputOutlineColor: { ...inputField$6, property: 'outline-color' },
@@ -2510,11 +2522,16 @@ var textFieldMappings = {
2510
2522
  inputOutlineWidth: { ...inputField$6, property: 'outline-width' },
2511
2523
  inputOutlineOffset: { ...inputField$6, property: 'outline-offset' },
2512
2524
 
2513
- inputTextAlign: { ...input, property: 'text-align' },
2525
+ inputTextAlign: [
2526
+ { ...input, property: 'text-align' },
2527
+ { ...externalInput, property: 'text-align' },
2528
+ ],
2514
2529
 
2515
2530
  inputPlaceholderColor: [
2516
2531
  { ...placeholder$3, property: 'color' },
2532
+ { ...externalPlaceholder, property: 'color' },
2517
2533
  { ...disabledPlaceholder, property: '-webkit-text-fill-color' },
2534
+ { ...externalDisabledPlaceholder, property: '-webkit-text-fill-color' },
2518
2535
  ],
2519
2536
  };
2520
2537
 
@@ -3010,6 +3027,31 @@ const customMixin$7 = (superclass) =>
3010
3027
  this.baseElement._setType(newVal);
3011
3028
  }
3012
3029
  }
3030
+
3031
+ // webauthn is not working when the native input element is nested inside multiple shadow roots
3032
+ // so we need to be able move the input outside the shadow root for some cases
3033
+ get isExternalInput() {
3034
+ return this.getAttribute('external-input') === 'true';
3035
+ }
3036
+
3037
+ constructor() {
3038
+ super();
3039
+
3040
+ if (this.isExternalInput) {
3041
+ const origInput = this.baseElement.querySelector('input');
3042
+ this.inputSlot = document.createElement('slot');
3043
+
3044
+ this.focus = () => {
3045
+ origInput.focus();
3046
+ };
3047
+
3048
+ this.inputSlot.setAttribute('name', 'input');
3049
+ this.inputSlot.setAttribute('slot', 'input');
3050
+ this.baseElement.appendChild(this.inputSlot);
3051
+
3052
+ this.appendChild(origInput);
3053
+ }
3054
+ }
3013
3055
  };
3014
3056
 
3015
3057
  const TextFieldClass = compose(
@@ -5338,7 +5380,7 @@ const componentName$v = getComponentName('phone-field-internal');
5338
5380
 
5339
5381
  const commonAttrs$1 = ['disabled', 'size', 'bordered', 'invalid', 'readonly'];
5340
5382
  const countryAttrs = ['country-input-placeholder', 'default-code', 'restrict-countries'];
5341
- const phoneAttrs = ['phone-input-placeholder', 'maxlength'];
5383
+ const phoneAttrs = ['phone-input-placeholder', 'maxlength', 'autocomplete', 'name'];
5342
5384
  const mapAttrs$1 = {
5343
5385
  'country-input-placeholder': 'placeholder',
5344
5386
  'phone-input-placeholder': 'placeholder',
@@ -5365,7 +5407,7 @@ let PhoneFieldInternal$1 = class PhoneFieldInternal extends BaseInputClass$6 {
5365
5407
  ${CountryCodes.map((item) => comboBoxItem(item)).join('')}
5366
5408
  </descope-combo-box>
5367
5409
  <div class="separator"></div>
5368
- <descope-text-field type="tel"></descope-text-field>
5410
+ <descope-text-field type="tel" external-input="true"></descope-text-field>
5369
5411
  </div>
5370
5412
  `;
5371
5413
 
@@ -5760,6 +5802,8 @@ const observedAttributes$2 = [
5760
5802
  'invalid',
5761
5803
  'readonly',
5762
5804
  'phone-input-placeholder',
5805
+ 'name',
5806
+ 'autocomplete',
5763
5807
  ];
5764
5808
  const mapAttrs = {
5765
5809
  'phone-input-placeholder': 'placeholder',
@@ -5777,7 +5821,7 @@ class PhoneFieldInternal extends BaseInputClass$5 {
5777
5821
 
5778
5822
  this.innerHTML = `
5779
5823
  <div>
5780
- <descope-text-field tabindex="1"></descope-text-field>
5824
+ <descope-text-field tabindex="1" external-input="true"></descope-text-field>
5781
5825
  </div>
5782
5826
  `;
5783
5827
 
@@ -6706,8 +6750,10 @@ class RawRecaptcha extends BaseClass {
6706
6750
 
6707
6751
  attributeChangedCallback(attrName, oldValue, newValue) {
6708
6752
  super.attributeChangedCallback?.(attrName, oldValue, newValue);
6709
- if (attrName === 'enabled') {
6710
- this.#toggleRecaptcha(newValue === 'true');
6753
+ if (oldValue !== newValue) {
6754
+ if (attrName === 'enabled') {
6755
+ this.#toggleRecaptcha(newValue === 'true');
6756
+ }
6711
6757
  }
6712
6758
  }
6713
6759
 
@@ -6777,73 +6823,89 @@ class RawRecaptcha extends BaseClass {
6777
6823
  #toggleRecaptcha(enabled) {
6778
6824
  this.renderRecaptcha(enabled);
6779
6825
  if (enabled) {
6780
- this.#loadRecaptchaScript();
6781
6826
  this.#createOnLoadScript();
6827
+ if (!document.getElementById('recaptcha-script')) {
6828
+ this.#loadRecaptchaScript();
6829
+ } else {
6830
+ window.onRecaptchaLoadCallback();
6831
+ }
6782
6832
  }
6783
6833
  }
6784
6834
 
6785
6835
  #loadRecaptchaScript() {
6786
- if (!document.getElementById('recaptcha-script')) {
6787
- const script = document.createElement('script');
6788
- script.src = this.scriptURL;
6789
- script.async = true;
6790
- script.id = 'recaptcha-script';
6791
- script.defer = true;
6792
- document.body.appendChild(script);
6793
- } else {
6794
- window.onRecaptchaLoadCallback();
6795
- }
6836
+ const script = document.createElement('script');
6837
+ script.src = this.scriptURL;
6838
+ script.async = true;
6839
+ script.id = 'recaptcha-script';
6840
+ script.defer = true;
6841
+ document.body.appendChild(script);
6796
6842
  }
6797
6843
 
6798
- #createOnLoadScript() {
6799
- if (window.onRecaptchaLoadCallback) {
6800
- return;
6801
- }
6844
+ get grecaptchaInstance() {
6845
+ return this.enterprise ? window.grecaptcha?.enterprise : window.grecaptcha;
6846
+ }
6802
6847
 
6848
+ #createOnLoadScript() {
6803
6849
  window.onRecaptchaLoadCallback = () => {
6804
6850
  const currentNode = this.recaptchaEle;
6851
+
6805
6852
  // if there are child nodes, it means that the recaptcha was already rendered
6806
6853
  if (currentNode.hasChildNodes()) {
6807
6854
  return;
6808
6855
  }
6809
- const grecaptchaInstance = this.enterprise
6810
- ? window.grecaptcha?.enterprise
6811
- : window.grecaptcha;
6856
+
6857
+ const { grecaptchaInstance } = this;
6812
6858
 
6813
6859
  if (!grecaptchaInstance) {
6814
6860
  return;
6815
6861
  }
6816
6862
 
6817
6863
  setTimeout(() => {
6818
- const view = grecaptchaInstance.render(currentNode, {
6864
+ // returns recaptchaWidgetId
6865
+ const recaptchaWidgetId = grecaptchaInstance.render(currentNode, {
6819
6866
  sitekey: this.siteKey,
6820
6867
  badge: 'inline',
6821
6868
  size: 'invisible',
6822
6869
  });
6870
+
6823
6871
  grecaptchaInstance.ready(() => {
6824
6872
  // clone the node and append it to the body so that it can be used by the grepcaptcha script
6825
- const cloneNode = currentNode.querySelector('#g-recaptcha-response')?.cloneNode();
6873
+ const cloneNode = currentNode
6874
+ .querySelector('textarea[name^="g-recaptcha-response"]')
6875
+ ?.cloneNode();
6826
6876
  if (cloneNode) {
6827
6877
  cloneNode.style.display = 'none';
6828
6878
  document.body.appendChild(cloneNode);
6829
6879
  }
6880
+
6881
+ // cleaning up the recaptcha element we added to the body
6882
+ const removeCloneNode = () => {
6883
+ cloneNode.remove();
6884
+ };
6885
+
6830
6886
  if (this.siteKey) {
6831
- grecaptchaInstance?.execute(view, { action: this.action }).then((token) => {
6832
- this.updateComponentsContext({
6833
- risktoken: token,
6834
- riskaction: this.action,
6887
+ // we should pass recaptchaWidgetId, but this does not allow us to run execute multiple times
6888
+ // also calling grecaptchaInstance.reset() does not work
6889
+ const exec = grecaptchaInstance?.execute(recaptchaWidgetId, { action: this.action });
6890
+ exec
6891
+ .then((token) => {
6892
+ this.updateComponentsContext({
6893
+ risktoken: token,
6894
+ riskaction: this.action,
6895
+ });
6896
+
6897
+ removeCloneNode();
6898
+ })
6899
+ .catch((e) => {
6900
+ removeCloneNode();
6901
+ // eslint-disable-next-line no-console
6902
+ console.warn('could not execute recaptcha', e);
6835
6903
  });
6836
- });
6837
6904
  }
6838
6905
  });
6839
6906
  }, 0);
6840
6907
  };
6841
6908
  }
6842
-
6843
- connectedCallback() {
6844
- super.connectedCallback?.();
6845
- this.#toggleRecaptcha(this.enabled);
6846
- }
6847
6909
  }
6848
6910
 
6849
6911
  const RecaptchaClass = compose(draggableMixin)(RawRecaptcha);