@salesforcedevs/dw-components 1.3.148-canary.27 → 1.3.148-canary.28

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/lwc.config.json CHANGED
@@ -15,6 +15,7 @@
15
15
  "dw/eventsList",
16
16
  "dw/instrumentation",
17
17
  "dw/j2sCardSequence",
18
+ "dw/j2sCardSequenceStep",
18
19
  "dw/j2sForm",
19
20
  "dw/newsletterForm",
20
21
  "dw/podcastSubscription",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforcedevs/dw-components",
3
- "version": "1.3.148-canary.27",
3
+ "version": "1.3.148-canary.28",
4
4
  "description": "Lightning web components for https://developer.salesforce.com",
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -1,6 +1,4 @@
1
1
  @import "dxHelpers/reset";
2
- @import "dxHelpers/text";
3
- @import "dxHelpers/card";
4
2
 
5
3
  :host {
6
4
  --dx-c-button-custom-color: var(--dx-g-blue-vibrant-50);
@@ -14,47 +12,3 @@
14
12
  dx-step-sequence {
15
13
  scroll-margin-top: var(--dx-g-global-header-height);
16
14
  }
17
-
18
- dx-step-sequence-step:last-child[data-has-primary-action="true"]
19
- dx-card-step::part(footer-container) {
20
- background-color: var(--dx-g-indigo-vibrant-95);
21
- border-radius: 8px;
22
- margin: 0 30px 30px 30px;
23
- }
24
-
25
- [slot="secondary-action-section"] {
26
- color: var(--dx-g-red-vibrant-50);
27
- position: relative;
28
- font-size: var(--dx-g-text-xs, 12px);
29
- font-family: var(--dx-g-font-sans);
30
- line-height: 18px;
31
- text-align: left;
32
- }
33
-
34
- .body-container li {
35
- line-height: var(--dx-g-text-2xl);
36
- }
37
-
38
- .body-container p:not(:last-child) {
39
- padding-bottom: 20px;
40
- }
41
-
42
- .body-markup {
43
- display: block;
44
- }
45
-
46
- .final-email-address {
47
- display: block;
48
- margin-top: 20px;
49
- line-height: 24px;
50
- color: var(--dx-g-blue-vibrant-50);
51
- }
52
-
53
- .referral-email-field {
54
- --dx-c-input-width: 100%;
55
- }
56
-
57
- .spinner-container {
58
- min-height: 200px;
59
- position: relative;
60
- }
@@ -8,73 +8,20 @@
8
8
  use-history={useHistory}
9
9
  >
10
10
  <template for:each={stepsData} for:item="stepDatum" for:index="index">
11
- <dx-step-sequence-step
12
- key={stepDatum.id}
13
- class={stepClassName}
14
- data-has-primary-action={hasPrimaryAction}
15
- >
16
- <dx-card-step
17
- header-icon-symbol={stepDatum.headerData.iconSymbol}
18
- header-icon-sprite={stepDatum.headerData.iconSprite}
19
- header-icon-color={stepDatum.headerData.iconColor}
20
- header-background-color={stepDatum.headerData.backgroundColor}
21
- header-text-color={stepDatum.headerData.textColor}
22
- show-step-number={stepDatum.showStepNumber}
23
- step-count={stepsData.length}
11
+ <dx-step-sequence-step key={stepDatum.id}>
12
+ <dw-j2s-card-sequence-step
13
+ country-options={countries}
14
+ is-loading={isLoading}
15
+ oncountrychange={handleCountryChange}
16
+ ongetstarted={handleGetStarted}
17
+ onformsubmit={handleFormSubmit}
18
+ recaptcha-token={recaptchaToken}
19
+ selected-country={selectedCountry}
20
+ step-datum={stepDatum}
24
21
  step-index={index}
25
- step-title={stepDatum.stepTitle}
26
- >
27
- <div slot="card-body" class="body-container">
28
- <template if:true={isLoading}>
29
- <div class="spinner-container">
30
- <dx-spinner
31
- size="large"
32
- variant="brand"
33
- ></dx-spinner>
34
- </div>
35
- </template>
36
- <template if:false={isLoading}>
37
- <span lwc:dom="manual" class="body-markup"></span>
38
- <template if:true={stepDatum.formData}>
39
- <dw-j2s-form
40
- id={stepDatum.formData.formId}
41
- countries={countries}
42
- form-metadata={stepDatum.formData}
43
- incoming-user-info={formIncomingUserInfo}
44
- onformvaliditychange={handleFormValidityChange}
45
- recaptcha-token={recaptchaToken}
46
- >
47
- <div slot="form-captcha-slot">
48
- <slot name="captcha-slot"></slot>
49
- </div>
50
- </dw-j2s-form>
51
- </template>
52
- </template>
53
- </div>
54
- <div slot="secondary-action-section">
55
- <span
56
- lwc:dom="manual"
57
- class="secondary-action-markup"
58
- ></span>
59
- </div>
60
- <div slot="primary-action-section">
61
- <dx-button
62
- if:true={hasPrimaryAction}
63
- class="primary-action"
64
- disabled={isJ2sFormInvalid}
65
- href={primaryActionLink}
66
- icon-sprite={stepDatum.primaryAction.iconSprite}
67
- icon-symbol={stepDatum.primaryAction.iconSymbol}
68
- loading={isLoading}
69
- onclick={primaryActionHandler}
70
- size="large"
71
- target={primaryActionLinkTarget}
72
- variant={primaryActionVariant}
73
- >
74
- {primaryActionText}
75
- </dx-button>
76
- </div>
77
- </dx-card-step>
22
+ step-total-count={stepsData.length}
23
+ user-info={formIncomingUserInfo}
24
+ ></dw-j2s-card-sequence-step>
78
25
  </dx-step-sequence-step>
79
26
  </template>
80
27
  </dx-step-sequence>
@@ -1,9 +1,8 @@
1
1
  import { api, LightningElement } from "lwc";
2
2
  import StepSequence from "dx/stepSequence";
3
3
  import { getListWithUuids } from "dxUtils/list";
4
- import { track } from "dxUtils/analytics";
5
4
  import { toJson } from "dxUtils/normalizers";
6
- import J2sForm from "dw/j2sForm";
5
+ import J2sCardSequenceStep from "dw/j2sCardSequenceStep";
7
6
 
8
7
  export type StepDatum = {
9
8
  bodyHtml?:
@@ -69,10 +68,8 @@ export type DrmFormData = {
69
68
  };
70
69
 
71
70
  export default class J2sCardSequence extends LightningElement {
72
- _didRenderStaticInnerHtml = false;
73
71
  _isDrmLoading = false;
74
72
  _isFormSubmitting = false;
75
- _isJ2sFormInvalid = false;
76
73
  _isTbidLoading = false;
77
74
  _recaptchaResetTimeoutId: number | null = null;
78
75
  _stepsData: StepDatum[] = [];
@@ -107,11 +104,11 @@ export default class J2sCardSequence extends LightningElement {
107
104
  });
108
105
  }
109
106
 
110
- private confirmedCountry = "";
111
- private countries = "[]";
107
+ private countries: any[] = [];
112
108
  private currentSequenceStep = 0;
113
109
  private formSubmissionFailureState: Partial<DrmFormData> | null = null;
114
110
  private recaptchaToken = "";
111
+ private selectedCountry = "";
115
112
  private sessionStorageId = "j2s-card-sequence";
116
113
  private tbidUserInfo: any; // TODO typings?
117
114
 
@@ -125,47 +122,6 @@ export default class J2sCardSequence extends LightningElement {
125
122
  return Boolean(this.tbidUserInfo);
126
123
  }
127
124
 
128
- private get isJ2sFormInvalid() {
129
- return this.currentSequenceStep === 1 ? this._isJ2sFormInvalid : false;
130
- }
131
- private set isJ2sFormInvalid(isFormInvalid: boolean) {
132
- this._isJ2sFormInvalid = isFormInvalid;
133
- }
134
-
135
- private get primaryAction() {
136
- return this.stepsData[this.currentSequenceStep || 0].primaryAction;
137
- }
138
-
139
- private get primaryActionLink() {
140
- const { link } = this.primaryAction;
141
- return typeof link === "string"
142
- ? link
143
- : link?.[this.confirmedCountry] || link?.default;
144
- }
145
-
146
- private get primaryActionText() {
147
- const { text } = this.primaryAction;
148
- return typeof text === "string"
149
- ? text
150
- : text[this.confirmedCountry] || text.default;
151
- }
152
-
153
- private get primaryActionVariant() {
154
- if (this.currentSequenceStep === 1 && this.isJ2sFormInvalid) {
155
- return "custom"; // override for disabled button styling
156
- }
157
- return this.primaryAction.variant;
158
- }
159
-
160
- private get primaryActionLinkTarget() {
161
- return this.primaryAction.linkTarget || "_blank";
162
- }
163
-
164
- private get hasPrimaryAction() {
165
- // new requirement: don't show primary action on final step if country isn't India
166
- return this.currentSequenceStep !== 2 || this.confirmedCountry === "IN";
167
- }
168
-
169
125
  private get formIncomingUserInfo() {
170
126
  if (!this.tbidUserInfo) {
171
127
  return {} as DrmFormData;
@@ -232,27 +188,30 @@ export default class J2sCardSequence extends LightningElement {
232
188
  }
233
189
 
234
190
  renderedCallback() {
235
- if (this.isLoading) {
236
- this._didRenderStaticInnerHtml = false; // only when `this.isLoading` is true will static HTML need to be re-rendered, since the content will have been replaced by the spinner
237
- return;
238
- }
239
-
240
- if (!this._didRenderStaticInnerHtml) {
241
- this.updateStaticInnerHtml();
242
- this._didRenderStaticInnerHtml = true;
191
+ if (!this.isLoading) {
192
+ (
193
+ this.template.querySelector(
194
+ "dx-step-sequence"
195
+ ) as unknown as StepSequence
196
+ )?.remeasureSteps();
243
197
  }
244
198
 
245
- if (this.formSubmissionFailureState) {
246
- const j2sFormEl = (this.template.querySelector(
247
- "dw-j2s-form"
248
- ) as unknown) as J2sForm | null;
249
- j2sFormEl?.notifySubmitFailure(this.formSubmissionFailureState);
199
+ if (
200
+ this.formSubmissionFailureState &&
201
+ this.stepsData[this.currentSequenceStep].formData
202
+ ) {
203
+ const j2sCardStep = this.template.querySelectorAll(
204
+ "dw-j2s-card-sequence-step"
205
+ ) as unknown as J2sCardSequenceStep[];
206
+ j2sCardStep[this.currentSequenceStep]?.notifyFormSubmitFailure(
207
+ this.formSubmissionFailureState
208
+ );
250
209
  this.formSubmissionFailureState = null;
251
210
  }
252
211
  }
253
212
 
254
- handleFormValidityChange({ detail }: CustomEvent) {
255
- this.isJ2sFormInvalid = !detail.isValid;
213
+ handleCountryChange({ detail }: CustomEvent) {
214
+ this.selectedCountry = detail;
256
215
  }
257
216
 
258
217
  handleStepSequenceChange({ detail }: CustomEvent) {
@@ -275,39 +234,26 @@ export default class J2sCardSequence extends LightningElement {
275
234
  }
276
235
  }
277
236
 
278
- handleGetStarted(evt: Event) {
237
+ handleGetStarted() {
279
238
  // If the user is not yet logged in, we need to prevent moving immediately to the next
280
239
  // step, but set storage up so that they are on the second step when they return to the
281
240
  // site in a logged-in state; then, we need to get them to log in.
282
241
  if (!this.isLoggedIn) {
283
- evt.preventDefault();
284
242
  this.initialStepIndex = 1;
285
243
  this._isTbidLoading = true;
286
244
  (window as any).__startTbidLogin?.(); // call out to DSC tbid controller
245
+ } else {
246
+ this.jumpToStepIndex(1);
287
247
  }
288
248
  }
289
249
 
290
- async handleFormSubmit(evt: Event) {
291
- if (!this.formHandler || this.isJ2sFormInvalid || !this.isLoggedIn) {
250
+ async handleFormSubmit({ detail: formData }: CustomEvent<DrmFormData>) {
251
+ if (!this.formHandler || !this.isLoggedIn) {
292
252
  return;
293
253
  }
294
254
 
295
- evt.preventDefault(); // don't proceed automatically to next step
296
255
  this._isFormSubmitting = true;
297
256
 
298
- const j2sFormEl = (this.template.querySelector(
299
- "dw-j2s-form"
300
- ) as unknown) as J2sForm;
301
- const formData = j2sFormEl.formDataForDrm;
302
-
303
- // For some countries, explicit approvals will be present; for others, it is implicitly assumed
304
- if (typeof formData.Opt_In__c !== "boolean") {
305
- formData.Opt_In__c = true;
306
- }
307
- if (typeof formData.Privacy_Statement__c !== "boolean") {
308
- formData.Privacy_Statement__c = true;
309
- }
310
-
311
257
  try {
312
258
  const res = await fetch(this.formHandler, {
313
259
  method: "POST",
@@ -326,7 +272,6 @@ export default class J2sCardSequence extends LightningElement {
326
272
  const resData = await res.json();
327
273
  const resOutput = resData.handlePostRequestOutput || resData;
328
274
  if (resOutput?.status === "success") {
329
- this.confirmedCountry = formData.MailingCountry as string;
330
275
  this.jumpToStepIndex(2, false);
331
276
  this.initialStepIndex = 0; // don't save final step in storage; rather, reset the starting step
332
277
  } else {
@@ -347,31 +292,6 @@ export default class J2sCardSequence extends LightningElement {
347
292
  this._isFormSubmitting = false;
348
293
  }
349
294
 
350
- primaryActionHandler(evt: Event) {
351
- const target = evt.target as HTMLButtonElement;
352
-
353
- if (!target || target.disabled) {
354
- evt.preventDefault();
355
- return;
356
- }
357
-
358
- track(target, "custEv_ctaButtonClick", {
359
- click_text: target.textContent,
360
- element_title: this.stepsData[this.currentSequenceStep].stepTitle,
361
- click_url:
362
- this.stepsData[this.currentSequenceStep].primaryAction.link ||
363
- "",
364
- element_type: "button",
365
- content_category: "cta"
366
- });
367
-
368
- if (!this.currentSequenceStep) {
369
- this.handleGetStarted(evt);
370
- } else if (this.currentSequenceStep === 1) {
371
- this.handleFormSubmit(evt);
372
- }
373
- }
374
-
375
295
  private resetCustomButtonColors() {
376
296
  let bgColor;
377
297
  let textColor;
@@ -402,54 +322,11 @@ export default class J2sCardSequence extends LightningElement {
402
322
  if (andStoreIndex) {
403
323
  this.initialStepIndex = stepIndex; // update sessionStorage value
404
324
  }
405
- ((this.template.querySelector(
406
- "dx-step-sequence"
407
- ) as unknown) as StepSequence)?.jumpToStep(stepIndex);
408
- }
409
-
410
- private updateStaticInnerHtml() {
411
- const bodyMarkupContainers = this.template.querySelectorAll(
412
- "span.body-markup"
413
- );
414
- const secondaryActionMarkupContainers = this.template.querySelectorAll(
415
- "span.secondary-action-markup"
416
- );
417
-
418
- this.stepsData.forEach((step, stepIndex) => {
419
- const { bodyHtml, secondaryActionHtml } = step;
420
- const bodyMarkupContainer = bodyMarkupContainers[stepIndex];
421
- const secondaryActionMarkupContainer =
422
- secondaryActionMarkupContainers[stepIndex];
423
-
424
- if (bodyMarkupContainer) {
425
- let markup =
426
- typeof bodyHtml === "string"
427
- ? bodyHtml
428
- : bodyHtml?.[this.confirmedCountry] ||
429
- bodyHtml?.default;
430
-
431
- if (stepIndex === 2) {
432
- // User's email is supposed to show on final step
433
- markup = `${markup}${
434
- !this.formIncomingUserInfo.Email
435
- ? ""
436
- : `<span class="final-email-address">${this.formIncomingUserInfo.Email}</span>`
437
- }`;
438
- }
439
-
440
- bodyMarkupContainer.innerHTML = markup || "";
441
- }
442
-
443
- if (secondaryActionMarkupContainer) {
444
- const secondaryActionInnerHtml =
445
- !secondaryActionHtml ||
446
- // ugh, new special exception on step 2 to only show secondary action for IN
447
- (stepIndex === 2 && this.confirmedCountry !== "IN")
448
- ? ""
449
- : secondaryActionHtml;
450
- secondaryActionMarkupContainer.innerHTML = secondaryActionInnerHtml;
451
- }
452
- });
325
+ (
326
+ this.template.querySelector(
327
+ "dx-step-sequence"
328
+ ) as unknown as StepSequence
329
+ )?.jumpToStep(stepIndex);
453
330
  }
454
331
 
455
332
  private async getCountryList() {
@@ -463,8 +340,7 @@ export default class J2sCardSequence extends LightningElement {
463
340
  if (!res.ok) {
464
341
  throw new Error(errorMsg);
465
342
  }
466
- const data = await res.json();
467
- this.countries = JSON.stringify(data);
343
+ this.countries = await res.json();
468
344
  } catch (error) {
469
345
  console.error(error);
470
346
  if (this.initialStepIndex > 0) {
@@ -484,6 +360,7 @@ export default class J2sCardSequence extends LightningElement {
484
360
  const res = await fetch(`${this.tbidApiBaseUrl}/userinfo`);
485
361
  if (res.ok) {
486
362
  this.tbidUserInfo = await res.json();
363
+ this.selectedCountry = this.formIncomingUserInfo.MailingCountry;
487
364
  }
488
365
  } catch (ex) {
489
366
  // noop; nothing to do here
@@ -0,0 +1,47 @@
1
+ @import "dxHelpers/reset";
2
+ @import "dxHelpers/text";
3
+ @import "dxHelpers/card";
4
+
5
+ /* Special styling for the final step's actions if they are shown */
6
+ dx-card-step.final-card-with-action::part(footer-container) {
7
+ background-color: var(--dx-g-indigo-vibrant-95);
8
+ border-radius: 8px;
9
+ margin: 0 30px 30px 30px;
10
+ }
11
+
12
+ [slot="secondary-action-section"] {
13
+ color: var(--dx-g-red-vibrant-50);
14
+ position: relative;
15
+ font-size: var(--dx-g-text-xs, 12px);
16
+ font-family: var(--dx-g-font-sans);
17
+ line-height: 18px;
18
+ text-align: left;
19
+ }
20
+
21
+ .body-container li {
22
+ line-height: var(--dx-g-text-2xl);
23
+ }
24
+
25
+ .body-container p:not(:last-child) {
26
+ padding-bottom: 20px;
27
+ }
28
+
29
+ .body-markup {
30
+ display: block;
31
+ }
32
+
33
+ .final-email-address {
34
+ display: block;
35
+ margin-top: 20px;
36
+ line-height: 24px;
37
+ color: var(--dx-g-blue-vibrant-50);
38
+ }
39
+
40
+ .referral-email-field {
41
+ --dx-c-input-width: 100%;
42
+ }
43
+
44
+ .spinner-container {
45
+ min-height: 200px;
46
+ position: relative;
47
+ }
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <dx-card-step
3
+ class={stepClassName}
4
+ header-icon-symbol={stepDatum.headerData.iconSymbol}
5
+ header-icon-sprite={stepDatum.headerData.iconSprite}
6
+ header-icon-color={stepDatum.headerData.iconColor}
7
+ header-background-color={stepDatum.headerData.backgroundColor}
8
+ header-text-color={stepDatum.headerData.textColor}
9
+ show-step-number={stepDatum.showStepNumber}
10
+ step-count={stepTotalCount}
11
+ step-index={stepIndex}
12
+ step-title={stepDatum.stepTitle}
13
+ >
14
+ <div slot="card-body" class="body-container">
15
+ <template if:true={isLoading}>
16
+ <div class="spinner-container">
17
+ <dx-spinner size="large" variant="brand"></dx-spinner>
18
+ </div>
19
+ </template>
20
+ <template if:false={isLoading}>
21
+ <span lwc:dom="manual" class="body-markup"></span>
22
+ <template if:true={stepDatum.formData}>
23
+ <dw-j2s-form
24
+ id={stepDatum.formData.formId}
25
+ countries={countryOptions}
26
+ form-metadata={stepDatum.formData}
27
+ incoming-user-info={userInfo}
28
+ onformvaliditychange={handleFormValidityChange}
29
+ recaptcha-token={recaptchaToken}
30
+ >
31
+ <div slot="form-captcha-slot">
32
+ <slot name="captcha-slot"></slot>
33
+ </div>
34
+ </dw-j2s-form>
35
+ </template>
36
+ </template>
37
+ </div>
38
+ <div slot="secondary-action-section">
39
+ <span lwc:dom="manual" class="secondary-action-markup"></span>
40
+ </div>
41
+ <div slot="primary-action-section">
42
+ <dx-button
43
+ if:true={showPrimaryAction}
44
+ class="primary-action"
45
+ disabled={isJ2sFormInvalid}
46
+ href={primaryActionLink}
47
+ icon-sprite={stepDatum.primaryAction.iconSprite}
48
+ icon-symbol={stepDatum.primaryAction.iconSymbol}
49
+ loading={isLoading}
50
+ onclick={handlePrimaryAction}
51
+ size="large"
52
+ target={primaryActionLinkTarget}
53
+ variant={primaryActionVariant}
54
+ >
55
+ {primaryActionText}
56
+ </dx-button>
57
+ </div>
58
+ </dx-card-step>
59
+ </template>
@@ -0,0 +1,152 @@
1
+ import { api, LightningElement } from "lwc";
2
+ import { DrmFormData, StepDatum } from "dw/j2sCardSequence";
3
+ import { track } from "dxUtils/analytics";
4
+ import J2sForm from "dw/j2sForm";
5
+
6
+ export default class J2sCardSequenceStep extends LightningElement {
7
+ @api countryOptions: any[] = [];
8
+ @api isLoading = false;
9
+ @api recaptchaToken = "";
10
+ @api selectedCountry = "";
11
+ @api stepDatum!: StepDatum;
12
+ @api stepIndex = 0;
13
+ @api stepTotalCount = 0;
14
+ @api userInfo: any = {};
15
+
16
+ @api
17
+ public notifyFormSubmitFailure(formFailureData: Partial<DrmFormData>) {
18
+ (
19
+ this.template.querySelector("dw-j2s-form") as unknown as J2sForm
20
+ )?.notifySubmitFailure(formFailureData);
21
+ }
22
+
23
+ private _isJ2sFormInvalid = false;
24
+
25
+ private get stepClassName() {
26
+ return this.stepIndex === 2 && this.selectedCountry === "IN"
27
+ ? "final-card-with-action"
28
+ : "";
29
+ }
30
+
31
+ private get isJ2sFormInvalid() {
32
+ return this.stepIndex === 1 && this._isJ2sFormInvalid;
33
+ }
34
+ private set isJ2sFormInvalid(value: boolean) {
35
+ this._isJ2sFormInvalid = value;
36
+ }
37
+
38
+ private get primaryActionLink() {
39
+ const { link } = this.stepDatum.primaryAction;
40
+ return typeof link === "string"
41
+ ? link
42
+ : link?.[this.selectedCountry] || link?.default;
43
+ }
44
+
45
+ private get primaryActionText() {
46
+ const { text } = this.stepDatum.primaryAction;
47
+ return typeof text === "string"
48
+ ? text
49
+ : text[this.selectedCountry] || text.default;
50
+ }
51
+
52
+ private get primaryActionVariant() {
53
+ if (this.stepIndex === 1 && this.isJ2sFormInvalid) {
54
+ return "custom"; // override for disabled button styling
55
+ }
56
+ return this.stepDatum.primaryAction.variant;
57
+ }
58
+
59
+ private get primaryActionLinkTarget() {
60
+ return this.stepDatum.primaryAction.linkTarget || "_blank";
61
+ }
62
+
63
+ private get showPrimaryAction() {
64
+ return this.stepIndex !== 2 || this.selectedCountry === "IN";
65
+ }
66
+
67
+ private get showSecondaryAction() {
68
+ return this.showPrimaryAction; // same requirement as above for now
69
+ }
70
+
71
+ renderedCallback() {
72
+ this.updateStaticInnerHtml();
73
+ }
74
+
75
+ handleFormValidityChange({ detail }: CustomEvent) {
76
+ this.isJ2sFormInvalid = !detail.isValid;
77
+ }
78
+
79
+ handlePrimaryAction(evt: Event) {
80
+ this.track(evt);
81
+
82
+ if (this.stepIndex === 0) {
83
+ this.dispatchEvent(new CustomEvent("getstarted"));
84
+ } else if (this.stepIndex === 1 && !this.isJ2sFormInvalid) {
85
+ const j2sFormEl = this.template.querySelector(
86
+ "dw-j2s-form"
87
+ ) as unknown as J2sForm;
88
+ const formData = j2sFormEl.formDataForDrm;
89
+
90
+ // For some countries, explicit approvals will be present; for others, it is implicitly assumed
91
+ if (typeof formData.Opt_In__c !== "boolean") {
92
+ formData.Opt_In__c = true;
93
+ }
94
+ if (typeof formData.Privacy_Statement__c !== "boolean") {
95
+ formData.Privacy_Statement__c = true;
96
+ }
97
+
98
+ this.dispatchEvent(
99
+ new CustomEvent("formsubmit", {
100
+ detail: formData
101
+ })
102
+ );
103
+ }
104
+ }
105
+
106
+ private updateStaticInnerHtml() {
107
+ const { bodyHtml, secondaryActionHtml } = this.stepDatum;
108
+ const bodyMarkupContainer =
109
+ this.template.querySelector("span.body-markup");
110
+ const secondaryActionMarkupContainer = this.template.querySelector(
111
+ "span.secondary-action-markup"
112
+ );
113
+
114
+ if (bodyMarkupContainer) {
115
+ let markup =
116
+ typeof bodyHtml === "string"
117
+ ? bodyHtml
118
+ : bodyHtml?.[this.selectedCountry] || bodyHtml?.default;
119
+
120
+ if (this.stepIndex === 2) {
121
+ // User's email is supposed to show on final step
122
+ markup = `${markup}${
123
+ !this.userInfo.Email
124
+ ? ""
125
+ : `<span class="final-email-address">${this.userInfo.Email}</span>`
126
+ }`;
127
+ }
128
+
129
+ bodyMarkupContainer.innerHTML = markup || "";
130
+ }
131
+
132
+ if (secondaryActionMarkupContainer) {
133
+ // new special exception on step 2 to only show secondary action for IN
134
+ secondaryActionMarkupContainer.innerHTML =
135
+ secondaryActionHtml && this.showSecondaryAction
136
+ ? secondaryActionHtml
137
+ : "";
138
+ }
139
+ }
140
+
141
+ private track(evt: Event) {
142
+ const target = evt.target as HTMLButtonElement;
143
+
144
+ track(target, "custEv_ctaButtonClick", {
145
+ click_text: target.textContent,
146
+ element_title: this.stepDatum.stepTitle,
147
+ click_url: this.stepDatum.primaryAction.link || "",
148
+ element_type: "button",
149
+ content_category: "cta"
150
+ });
151
+ }
152
+ }
@@ -203,10 +203,8 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
203
203
  handleFormFieldChange = (evt: CustomEvent) => {
204
204
  // Event target information must be read prior to debouncing; the target is gone after the debounce.
205
205
  const { target = {}, detail } = evt;
206
- const {
207
- name: targetName,
208
- required: isRequiredField
209
- } = target as HTMLInputElement;
206
+ const { name: targetName, required: isRequiredField } =
207
+ target as HTMLInputElement;
210
208
  const value =
211
209
  typeof detail === "string"
212
210
  ? detail
@@ -279,6 +277,14 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
279
277
  showMarketingText: countryData.showMarketingText
280
278
  });
281
279
 
280
+ this.dispatchEvent(
281
+ new CustomEvent("countrychange", {
282
+ bubbles: true,
283
+ composed: true,
284
+ detail: countryCode
285
+ })
286
+ );
287
+
282
288
  // Because updating the country can update the required fields, we need to re-set form
283
289
  // validity _after_ render
284
290
  requestAnimationFrame(() =>
@@ -301,7 +307,7 @@ export default class J2sForm extends LightningElementWithState<J2sFormState> {
301
307
 
302
308
  private checkValidity() {
303
309
  return (
304
- // Boolean(this.recaptchaToken) &&
310
+ Boolean(this.recaptchaToken) &&
305
311
  this.isParticipatingCountry(this.state.MailingCountry) &&
306
312
  this.requiredFormFields.every(
307
313
  (requiredFormField) =>