@descope/web-components-ui 1.0.308 → 1.0.310

Sign up to get free protection for your applications and to get access to all the features.
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);