@salesforcedevs/dw-components 1.3.397-canary.4 → 1.3.397-canary.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dw-components",
3
- "version": "1.3.397-canary.4",
3
+ "version": "1.3.397-canary.6",
4
4
  "description": "Lightning web components for https://developer.salesforce.com",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -4,7 +4,7 @@ import { track as trackGtm } from "dxUtils/analytics";
4
4
  import { submitForm, ErrorCode, SignupForm, UserData } from "./submitForm";
5
5
  import { CountryOptions } from "typings/custom";
6
6
  import { stateMap } from "dwUtils/forms";
7
- import Recaptcha from "packages/@salesforcedevs/dw-components/src/modules/dw/recaptcha/recaptcha";
7
+ import Recaptcha from "dw/recaptcha";
8
8
 
9
9
  type SelectOption = { value: string; label: string };
10
10
  type Country = SelectOption & {
@@ -86,7 +86,9 @@ export default class DeSignupForm extends LightningElement {
86
86
  }
87
87
 
88
88
  onSlotChange(e: Event) {
89
- this.recaptchaComponent = e.target as Recaptcha;
89
+ this.recaptchaComponent = (
90
+ e.target as HTMLSlotElement
91
+ )?.assignedElements()[0] as unknown as Recaptcha;
90
92
  }
91
93
 
92
94
  createUUID() {
@@ -1,13 +1,6 @@
1
1
  @import "dxHelpers/reset";
2
2
  @import "dxHelpers/text";
3
3
 
4
- .container {
5
- width: 100%;
6
- display: flex;
7
- justify-content: center;
8
- margin-bottom: var(--dx-g-spacing-lg);
9
- }
10
-
11
4
  .error-message-box {
12
5
  margin-top: var(--dx-g-spacing-xs);
13
6
  display: block;
@@ -1,25 +1,37 @@
1
1
  import { api, LightningElement } from "lwc";
2
2
 
3
- declare module globalThis {
4
- let grecaptcha: {
5
- render(element: HTMLElement | null, recaptchaConfig: any): void;
6
- reset(): void;
7
- };
8
- }
3
+ // NOTE: This component assumes it is the only Recaptcha widget on a page.
4
+ type RecaptchaApi = {
5
+ render(element: HTMLElement | null, recaptchaConfig: any): void;
6
+ reset(): void;
7
+ };
9
8
 
10
9
  export default class Recaptcha extends LightningElement {
11
- private _recaptchaToken = "";
10
+ private didRenderRecaptcha = false;
12
11
  private errorMessage = "";
13
- private slottedRecaptchaDiv: HTMLDivElement | null = null;
12
+ private recaptchaDiv?: HTMLDivElement;
13
+ private recaptchaApi?: RecaptchaApi;
14
+ private recaptchaToken = "";
14
15
 
15
16
  @api missingErrorMessage = "Complete the captcha";
16
17
  @api recaptchaSiteKey = "";
17
18
 
18
19
  @api // read only
19
20
  get value() {
20
- return this._recaptchaToken;
21
+ return this.recaptchaToken;
21
22
  }
22
23
 
24
+ @api
25
+ recaptchaScriptOnLoad = (recaptchaApi: RecaptchaApi) => {
26
+ // store callbacks to be used with recaptcha
27
+ this.recaptchaApi = recaptchaApi;
28
+
29
+ // and if we have everything needed to render, render
30
+ if (this.recaptchaDiv) {
31
+ this.renderRecaptcha();
32
+ }
33
+ };
34
+
23
35
  @api
24
36
  reset = () => this.resetRecaptcha();
25
37
 
@@ -36,38 +48,48 @@ export default class Recaptcha extends LightningElement {
36
48
 
37
49
  @api
38
50
  checkValidity = () => {
39
- return Boolean(
40
- (
41
- this.slottedRecaptchaDiv?.querySelector(
42
- "#g-recaptcha-response"
43
- ) as HTMLTextAreaElement
44
- )?.value
45
- );
51
+ return Boolean(this.recaptchaToken);
46
52
  };
47
53
 
48
- private onSlotChange(e: Event) {
49
- this.slottedRecaptchaDiv = e.target as HTMLDivElement;
54
+ private onSlotChange = (e: Event) => {
55
+ this.recaptchaDiv = (
56
+ e.target as HTMLSlotElement
57
+ )?.assignedElements?.()[0] as HTMLDivElement;
58
+
59
+ // if we have everything needed to render, render
60
+ if (this.recaptchaApi) {
61
+ this.renderRecaptcha();
62
+ }
63
+ };
64
+
65
+ private renderRecaptcha = () => {
66
+ if (this.didRenderRecaptcha) {
67
+ return;
68
+ }
69
+
50
70
  const smallMatchMedia = window.matchMedia(
51
71
  "screen and (max-width: 768px)"
52
72
  );
53
73
 
54
74
  // render recaptcha, referencing this component's callbacks for handling events
55
- globalThis.grecaptcha?.render(this.slottedRecaptchaDiv, {
75
+ this.recaptchaApi?.render(this.recaptchaDiv as HTMLDivElement, {
56
76
  sitekey: this.recaptchaSiteKey,
57
77
  callback: this.recaptchaCallback,
58
78
  "expired-callback": this.recaptchaExpiredCallback,
59
79
  "error-callback": this.recaptchaErrorCallback,
60
80
  size: smallMatchMedia.matches ? "compact" : "normal"
61
81
  });
62
- }
82
+
83
+ this.didRenderRecaptcha = true;
84
+ };
63
85
 
64
86
  private recaptchaCallback = (token: string) => {
65
- this._recaptchaToken = token;
87
+ this.recaptchaToken = token;
66
88
  this.errorMessage = "";
67
89
  };
68
90
 
69
91
  private recaptchaExpiredCallback = () => {
70
- this._recaptchaToken = ""; // note: recaptcha element itself handles showing an "expired" message
92
+ this.recaptchaToken = ""; // note: recaptcha element itself handles showing an "expired" message
71
93
  };
72
94
 
73
95
  private recaptchaErrorCallback = () => {
@@ -76,7 +98,7 @@ export default class Recaptcha extends LightningElement {
76
98
  };
77
99
 
78
100
  private resetRecaptcha = () => {
79
- this._recaptchaToken = "";
80
- globalThis.grecaptcha?.reset();
101
+ this.recaptchaToken = "";
102
+ this.recaptchaApi?.reset();
81
103
  };
82
104
  }