@descope/web-components-ui 3.19.0 → 3.20.0

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.
@@ -1,6 +1,6 @@
1
1
  import { injectStyle } from '@descope-ui/common/components-helpers';
2
2
  import { draggableMixin } from '../../mixins';
3
- import { createBaseClass } from '../../baseClasses/createBaseClass';
3
+ import { createBaseInputClass } from '../../baseClasses/createBaseInputClass';
4
4
  import { compose } from '../../helpers';
5
5
  import { getComponentName, observeChildren } from '../../helpers/componentHelpers';
6
6
 
@@ -8,13 +8,19 @@ export const componentName = getComponentName('recaptcha');
8
8
 
9
9
  const observedAttributes = ['enabled', 'site-key', 'action', 'enterprise', 'variant'];
10
10
 
11
- const BaseClass = createBaseClass({
11
+ // The runtime only validates elements carrying a `name` (querySelectorAll('*[name]')).
12
+ const DEFAULT_FIELD_NAME = 'recaptcha';
13
+
14
+ const BaseInputClass = createBaseInputClass({
12
15
  componentName,
13
16
  baseSelector: ':host > div',
14
17
  });
15
- class RawRecaptcha extends BaseClass {
18
+ class RawRecaptcha extends BaseInputClass {
19
+ /** The exact `name` this component wrote itself, or null if the name is not ours. */
20
+ #ownedFieldName = null;
21
+
16
22
  static get observedAttributes() {
17
- return observedAttributes.concat(BaseClass.observedAttributes || []);
23
+ return observedAttributes.concat(BaseInputClass.observedAttributes || []);
18
24
  }
19
25
 
20
26
  attributeChangedCallback(attrName, oldValue, newValue) {
@@ -25,6 +31,7 @@ class RawRecaptcha extends BaseClass {
25
31
  }
26
32
 
27
33
  if (attrName === 'variant') {
34
+ this.#syncFormField();
28
35
  this.updatePreview();
29
36
  }
30
37
  }
@@ -40,7 +47,7 @@ class RawRecaptcha extends BaseClass {
40
47
  }
41
48
 
42
49
  displayRecaptcha() {
43
- if (this.isWidget) {
50
+ if (this.isWidgetVariant) {
44
51
  this.displayWidget();
45
52
  } else {
46
53
  this.displayDeprecated();
@@ -135,6 +142,31 @@ class RawRecaptcha extends BaseClass {
135
142
  super.init?.();
136
143
 
137
144
  observeChildren(this, this.updatePreview.bind(this));
145
+ // avoid any possible conflicts with the inner input element
146
+ this.inputElement = this.recaptchaWidgetInputEle;
147
+ this.recaptchaWidgetInputEle.getValidity = null;
148
+ this.recaptchaWidgetInputEle.checkValidity = null;
149
+ this.#syncFormField();
150
+ }
151
+
152
+ /**
153
+ * Only the widget variant is a form field — the others must not carry a name, or the screen
154
+ * would submit an always-empty value under it.
155
+ */
156
+ #syncFormField() {
157
+ if (this.isWidgetVariant) {
158
+ if (!this.getAttribute('name')) {
159
+ this.setAttribute('name', DEFAULT_FIELD_NAME);
160
+ this.#ownedFieldName = DEFAULT_FIELD_NAME;
161
+ }
162
+ } else if (this.#ownedFieldName && this.getAttribute('name') === this.#ownedFieldName) {
163
+ this.removeAttribute('name');
164
+ this.#ownedFieldName = null;
165
+ }
166
+
167
+ // Refreshes the mixin's cached validity, which reportValidity answers from. Non-bubbling on
168
+ // purpose: the flow must not read this as user input.
169
+ this.dispatchEvent(new Event('change'));
138
170
  }
139
171
 
140
172
  updatePreview() {
@@ -150,7 +182,7 @@ class RawRecaptcha extends BaseClass {
150
182
  }
151
183
 
152
184
  getValidity() {
153
- if (!this.isWidget) {
185
+ if (!this.isWidgetVariant) {
154
186
  return {};
155
187
  }
156
188
 
@@ -162,7 +194,7 @@ class RawRecaptcha extends BaseClass {
162
194
  }
163
195
 
164
196
  checkValidity() {
165
- if (!this.isWidget) {
197
+ if (!this.isWidgetVariant) {
166
198
  return true;
167
199
  }
168
200
 
@@ -189,7 +221,7 @@ class RawRecaptcha extends BaseClass {
189
221
  return this.getAttribute('variant') || 'text';
190
222
  }
191
223
 
192
- get isWidget() {
224
+ get isWidgetVariant() {
193
225
  return this.variant === 'widget';
194
226
  }
195
227
 
@@ -203,7 +235,7 @@ class RawRecaptcha extends BaseClass {
203
235
 
204
236
  #toggleRecaptcha(enabled) {
205
237
  this.renderRecaptcha(enabled);
206
- if (this.isWidget) {
238
+ if (this.isWidgetVariant) {
207
239
  // For the interactive widget, scripts are loaded/executed by the runtime (grecaptcha-v2 for the
208
240
  // v2 checkbox, grecaptcha for an Enterprise key). This legacy v3/invisible path must be fully
209
241
  // skipped — the runtime renders into #recaptcha-widget and fills #recaptcha-widget-input.