@salesforcedevs/dx-components 1.3.179 → 1.3.180-alpha
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 +1 -4
- package/package.json +2 -3
- package/src/modules/dx/button/button.css +1 -4
- package/src/modules/dx/button/button.ts +2 -18
- package/src/modules/dx/checkbox/checkbox.ts +2 -26
- package/src/modules/dx/featuresListHeader/featuresListHeader.css +1 -6
- package/src/modules/dx/featuresListHeader/featuresListHeader.html +1 -3
- package/src/modules/dx/featuresListHeader/featuresListHeader.ts +1 -14
- package/src/modules/dx/input/input.css +0 -4
- package/src/modules/dx/input/input.html +0 -1
- package/src/modules/dx/input/input.ts +7 -56
- package/src/modules/dx/scrollManager/scrollManager.ts +0 -1
- package/src/modules/dx/sectionBanner/sectionBanner.css +1 -57
- package/src/modules/dx/sectionBanner/sectionBanner.html +4 -18
- package/src/modules/dx/sectionBanner/sectionBanner.ts +3 -96
- package/src/modules/dx/select/select.ts +5 -28
- package/src/modules/dx/stepSequence/stepSequence.css +4 -0
- package/src/modules/dx/stepSequence/stepSequence.html +1 -2
- package/src/modules/dx/stepSequence/stepSequence.ts +34 -139
- package/src/modules/dx/trafficLabeler/trafficLabeler.html +1 -0
- package/src/modules/dx/trafficLabeler/trafficLabeler.ts +66 -0
- package/src/modules/dxUtils/css/css.ts +1 -4
- package/src/modules/dxUtils/lwc/lwc.ts +0 -15
- package/LICENSE +0 -12
- package/src/modules/dx/alert/alert.css +0 -108
- package/src/modules/dx/alert/alert.html +0 -36
- package/src/modules/dx/alert/alert.ts +0 -137
- package/src/modules/dx/cardStep/cardStep.css +0 -128
- package/src/modules/dx/cardStep/cardStep.html +0 -31
- package/src/modules/dx/cardStep/cardStep.ts +0 -55
- package/src/modules/dx/cardStep/mockProps.ts +0 -60
- package/src/modules/dxBaseElements/lightningElementWithState/lightningElementWithState.ts +0 -93
- package/src/modules/dxUtils/list/list.ts +0 -11
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { LightningElement, api } from "lwc";
|
|
2
|
-
import cx from "classnames";
|
|
3
|
-
|
|
4
|
-
import { AlertInfo } from "typings/custom";
|
|
5
|
-
import { toJson } from "dxUtils/normalizers";
|
|
6
|
-
|
|
7
|
-
export default class Alert extends LightningElement {
|
|
8
|
-
_alertInfo: AlertInfo | null = null;
|
|
9
|
-
_dismissible = false;
|
|
10
|
-
_iconName = "";
|
|
11
|
-
_iconSprite = "";
|
|
12
|
-
_iconColor = "";
|
|
13
|
-
@api control: "none" | "hideable" | "dismissible" = "none";
|
|
14
|
-
@api type: "success" | "warning" | "danger" = "warning";
|
|
15
|
-
@api variant: "base" | "accented" = "base";
|
|
16
|
-
|
|
17
|
-
@api
|
|
18
|
-
get alertInfo(): AlertInfo | null {
|
|
19
|
-
return this._alertInfo;
|
|
20
|
-
}
|
|
21
|
-
set alertInfo(value) {
|
|
22
|
-
this._alertInfo = toJson(value);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
@api
|
|
26
|
-
get iconColor(): string {
|
|
27
|
-
return this._iconColor || this.variant === "base"
|
|
28
|
-
? "gray-10"
|
|
29
|
-
: this.accentedIconColor;
|
|
30
|
-
}
|
|
31
|
-
set iconColor(value) {
|
|
32
|
-
if (value) {
|
|
33
|
-
this._iconColor = value;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
@api
|
|
38
|
-
get iconName(): string {
|
|
39
|
-
return this._iconName || this.type === "success"
|
|
40
|
-
? "check-circle"
|
|
41
|
-
: "warning";
|
|
42
|
-
}
|
|
43
|
-
set iconName(value) {
|
|
44
|
-
if (value) {
|
|
45
|
-
this._iconName = value;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
@api
|
|
50
|
-
get iconSprite(): string {
|
|
51
|
-
return this._iconSprite || this.type === "success"
|
|
52
|
-
? "general"
|
|
53
|
-
: "utility";
|
|
54
|
-
}
|
|
55
|
-
set iconSprite(value) {
|
|
56
|
-
if (value) {
|
|
57
|
-
this._iconSprite = value;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
get accentedIconColor() {
|
|
62
|
-
const baseColor =
|
|
63
|
-
this.type === "danger"
|
|
64
|
-
? "red"
|
|
65
|
-
: this.type === "warning"
|
|
66
|
-
? "yellow"
|
|
67
|
-
: "green";
|
|
68
|
-
return `${baseColor}-vibrant-50`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
get dismissible(): boolean {
|
|
72
|
-
return this.control === "dismissible";
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
get hideable(): boolean {
|
|
76
|
-
return this.control === "hideable";
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
get alertTitle() {
|
|
80
|
-
return this.alertInfo?.title;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
get hideBodyText() {
|
|
84
|
-
return this.isBodyHidden ? "Show" : "Hide";
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
get alertType() {
|
|
88
|
-
return this.type || "warning";
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
get alertVariant() {
|
|
92
|
-
return this.variant || "base";
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
get className() {
|
|
96
|
-
return cx(
|
|
97
|
-
"alert-base",
|
|
98
|
-
"alert-container",
|
|
99
|
-
`alert-variant-${this.alertVariant}`,
|
|
100
|
-
`alert-type-${this.alertType}`
|
|
101
|
-
);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
get bodyClassName() {
|
|
105
|
-
return cx(
|
|
106
|
-
"alert-body",
|
|
107
|
-
"dx-text-body-3",
|
|
108
|
-
this.isBodyHidden && "alert-body-hidden"
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
isBodyHidden = false;
|
|
113
|
-
|
|
114
|
-
renderedCallback() {
|
|
115
|
-
const phaseBodyContainer = this.template.querySelector(".alert-body");
|
|
116
|
-
if (phaseBodyContainer && this.alertInfo) {
|
|
117
|
-
// eslint-disable-next-line @lwc/lwc/no-inner-html
|
|
118
|
-
phaseBodyContainer.innerHTML = this.alertInfo.body;
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
onShowHide() {
|
|
123
|
-
this.isBodyHidden = !this.isBodyHidden;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
onDismiss() {
|
|
127
|
-
this.dispatchEvent(
|
|
128
|
-
new CustomEvent("dismissphase", {
|
|
129
|
-
detail: {
|
|
130
|
-
alertInfo: this.alertInfo
|
|
131
|
-
},
|
|
132
|
-
composed: true,
|
|
133
|
-
bubbles: true
|
|
134
|
-
})
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
@import "dxHelpers/reset";
|
|
2
|
-
@import "dxHelpers/text";
|
|
3
|
-
@import "dxHelpers/card";
|
|
4
|
-
|
|
5
|
-
.container {
|
|
6
|
-
margin: var(--dx-c-card-step-container-margin, 40px auto);
|
|
7
|
-
max-width: 90%;
|
|
8
|
-
width: var(--dx-c-card-step-container-width, 796px);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.header-container {
|
|
12
|
-
background-color: var(
|
|
13
|
-
--dx-c-card-step-header-background-color,
|
|
14
|
-
var(--dx-g-indigo-vibrant-20)
|
|
15
|
-
);
|
|
16
|
-
padding: var(--dw-card-sequence-header-padding, var(--dx-g-spacing-3xl));
|
|
17
|
-
text-align: center;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.header-container > * {
|
|
21
|
-
display: inline-block;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.card-title {
|
|
25
|
-
color: var(--dx-c-card-step-header-text-color, white);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.card-title-icon {
|
|
29
|
-
height: 40px;
|
|
30
|
-
padding-right: 16px;
|
|
31
|
-
vertical-align: top;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.body-container {
|
|
35
|
-
font-family: var(--dx-g-font-display);
|
|
36
|
-
font-size: var(--dx-g-text-base);
|
|
37
|
-
font-weight: var(--dx-g-font-demi);
|
|
38
|
-
padding: var(--dw-card-sequence-body-padding, var(--dx-g-spacing-xl));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.footer-container {
|
|
42
|
-
display: flex;
|
|
43
|
-
align-items: center;
|
|
44
|
-
justify-content: space-between;
|
|
45
|
-
padding: var(--dw-card-sequence-body-padding, var(--dx-g-spacing-xl));
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.footer-section {
|
|
49
|
-
display: flex;
|
|
50
|
-
flex: 1;
|
|
51
|
-
justify-content: center;
|
|
52
|
-
order: 1; /* all have same order by default, i.e., source code order */
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.footer-section:first-child {
|
|
56
|
-
justify-content: start;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.footer-section:last-child {
|
|
60
|
-
justify-content: end;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
.footer-section:nth-child(2) {
|
|
64
|
-
flex: 0.7;
|
|
65
|
-
font-size: var(--dx-g-text-xs, 12px);
|
|
66
|
-
font-family: var(--dx-g-font-sans);
|
|
67
|
-
line-height: 18px;
|
|
68
|
-
text-align: center;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@media screen and (max-width: 768px) {
|
|
72
|
-
.footer-container {
|
|
73
|
-
flex-wrap: wrap;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.footer-section:first-child {
|
|
77
|
-
flex: 1 1 35%;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.footer-section:last-child {
|
|
81
|
-
flex: 1 1 65%;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.footer-section:nth-child(2) {
|
|
85
|
-
flex: 2 1 100%;
|
|
86
|
-
order: 2; /* force the "step x of y" component to be last, and take a full row */
|
|
87
|
-
padding-top: var(--dx-g-spacing-lg);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
@media screen and (max-width: 480px) {
|
|
92
|
-
.card-title {
|
|
93
|
-
font-size: var(--dx-g-text-xl);
|
|
94
|
-
line-height: 32px;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.card-title-icon {
|
|
98
|
-
height: unset;
|
|
99
|
-
padding-right: unset;
|
|
100
|
-
padding-bottom: 10px;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
.header-container {
|
|
104
|
-
padding: var(--dw-card-sequence-header-padding, var(--dx-g-spacing-xl));
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
.body-container {
|
|
108
|
-
padding-bottom: 0;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
.footer-container {
|
|
112
|
-
padding-top: 0;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
.footer-section:first-child,
|
|
116
|
-
.footer-section:nth-child(2),
|
|
117
|
-
.footer-section:last-child {
|
|
118
|
-
flex: 1 1 100%;
|
|
119
|
-
justify-content: center;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
@media screen and (max-width: 320px) {
|
|
124
|
-
.footer-container {
|
|
125
|
-
padding-left: 10px;
|
|
126
|
-
padding-right: 10px;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="dx-card-base container">
|
|
3
|
-
<div if:true={stepTitle} class="header-container">
|
|
4
|
-
<dx-icon
|
|
5
|
-
if:true={hasDefinedIcon}
|
|
6
|
-
class="card-title-icon"
|
|
7
|
-
size="xlarge"
|
|
8
|
-
color={headerIconColor}
|
|
9
|
-
sprite={headerIconSprite}
|
|
10
|
-
symbol={headerIconSymbol}
|
|
11
|
-
></dx-icon>
|
|
12
|
-
<h3 class="card-title dx-text-display-5">{stepTitle}</h3>
|
|
13
|
-
</div>
|
|
14
|
-
<div class="body-container">
|
|
15
|
-
<slot name="card-body"></slot>
|
|
16
|
-
</div>
|
|
17
|
-
<div class="footer-container" part="footer-container">
|
|
18
|
-
<div class="footer-section">
|
|
19
|
-
<slot name="secondary-action-section"></slot>
|
|
20
|
-
</div>
|
|
21
|
-
<div class="footer-section">
|
|
22
|
-
<span if:true={showStepNumber} class="step-id">
|
|
23
|
-
{stepDetails}
|
|
24
|
-
</span>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="footer-section">
|
|
27
|
-
<slot name="primary-action-section"></slot>
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
</div>
|
|
31
|
-
</template>
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { api, LightningElement } from "lwc";
|
|
2
|
-
import { toDxColor } from "dxUtils/css";
|
|
3
|
-
|
|
4
|
-
export type HeaderData = {
|
|
5
|
-
backgroundColor?: string;
|
|
6
|
-
iconColor?: string;
|
|
7
|
-
iconSymbol?: string;
|
|
8
|
-
iconSprite?: string;
|
|
9
|
-
textColor?: string;
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
export default class CardStep extends LightningElement {
|
|
13
|
-
@api headerIconColor = "";
|
|
14
|
-
@api headerIconSymbol = "";
|
|
15
|
-
@api headerIconSprite = "";
|
|
16
|
-
@api headerBackgroundColor = "indigo-vibrant-20";
|
|
17
|
-
@api headerTextColor = "white";
|
|
18
|
-
@api showStepNumber = false;
|
|
19
|
-
@api stepCount: number | undefined;
|
|
20
|
-
@api stepFormatString: string | undefined;
|
|
21
|
-
@api stepIndex: number | undefined;
|
|
22
|
-
@api stepTitle: string | undefined;
|
|
23
|
-
|
|
24
|
-
get stepDetails() {
|
|
25
|
-
if (
|
|
26
|
-
typeof this.stepIndex !== "number" ||
|
|
27
|
-
typeof this.stepCount !== "number"
|
|
28
|
-
) {
|
|
29
|
-
return "";
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const displayStepNumber = this.stepIndex + 1;
|
|
33
|
-
|
|
34
|
-
return this.stepFormatString
|
|
35
|
-
? this.stepFormatString
|
|
36
|
-
.replace("%d", displayStepNumber.toString())
|
|
37
|
-
.replace("%d", this.stepCount.toString())
|
|
38
|
-
: `Step ${displayStepNumber} of ${this.stepCount}`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
get hasDefinedIcon() {
|
|
42
|
-
return Boolean(this.headerIconSymbol && this.headerIconSprite);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
connectedCallback() {
|
|
46
|
-
this.template.host.style.setProperty(
|
|
47
|
-
"--dx-c-card-step-header-background-color",
|
|
48
|
-
toDxColor(this.headerBackgroundColor)
|
|
49
|
-
);
|
|
50
|
-
this.template.host.style.setProperty(
|
|
51
|
-
"--dx-c-card-step-header-text-color",
|
|
52
|
-
toDxColor(this.headerTextColor)
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
export const stepsData = [
|
|
2
|
-
{
|
|
3
|
-
bodyHtml:
|
|
4
|
-
'<p class="dx-text-display-7">Register for Journey to Salesforce and you\'ll be on your way to becoming a Salesforce Developer.</p><ul class="dx-text-display-8"><li>Step 1: Log in or sign up for a free Trailblazer.me account</li><li>Step 2: Confirm your program registration</li><li>Step 3: Begin your journey!</li></ul>',
|
|
5
|
-
primaryAction: {
|
|
6
|
-
iconSprite: "general",
|
|
7
|
-
iconSymbol: "arrow-right",
|
|
8
|
-
text: "Get Started",
|
|
9
|
-
variant: "primary"
|
|
10
|
-
},
|
|
11
|
-
showStepNumber: "true",
|
|
12
|
-
stepTitle: "Get started now."
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
bodyHtml:
|
|
16
|
-
'<p class="dx-text-display-7">You\'re almost done! Please review your information and agree to the Journey to Salesforce program terms and conditions.</p>',
|
|
17
|
-
formData: {
|
|
18
|
-
countriesWithReferralInput: ["IN"],
|
|
19
|
-
countriesWithRequiredJobRole: ["CA"],
|
|
20
|
-
formId: "j2s-form",
|
|
21
|
-
j2sTerms:
|
|
22
|
-
'I agree to the Journey to Salesforce Program Terms, subject to the <a href="http://www.google.com">Salesforce Program Agreement</a>.',
|
|
23
|
-
notAvailableAlertInfo: {
|
|
24
|
-
title: "Not Available",
|
|
25
|
-
body:
|
|
26
|
-
'The Journey to Salesforce program is not currently available in your country. See the <a href="https://www.google.com/">program FAQs</a> for a list of participating countries.'
|
|
27
|
-
},
|
|
28
|
-
participatingCountryCodes: ["US", "CA", "IN"]
|
|
29
|
-
},
|
|
30
|
-
primaryAction: {
|
|
31
|
-
text: "Complete Registration"
|
|
32
|
-
},
|
|
33
|
-
secondaryActionHtml:
|
|
34
|
-
'<span class="required-notice">* Required to participate in Journey to Salesforce</span>',
|
|
35
|
-
showStepNumber: "true",
|
|
36
|
-
stepTitle: "Complete your registration."
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
bodyHtml:
|
|
40
|
-
'<div class="dx-text-display-8"><p>Welcome to Journey to Salesforce! Congratulations on taking this step in your journey towards becoming a Salesforce Developer. Through this program you\'ll gain the knowledge, experience, and skills to help you excel in the Salesforce ecosystem.</p><p>To get started, click the button below to join the Journey to Salesforce community, and make sure to check your email for links to bookmark!</p></div>',
|
|
41
|
-
headerData: {
|
|
42
|
-
backgroundColor: "green-vibrant-95",
|
|
43
|
-
iconSymbol: "check-circle",
|
|
44
|
-
iconSprite: "general",
|
|
45
|
-
iconColor: "green-vibrant-65",
|
|
46
|
-
textColor: "indigo-vibrant-20"
|
|
47
|
-
},
|
|
48
|
-
primaryAction: {
|
|
49
|
-
iconSprite: "utility",
|
|
50
|
-
iconSymbol: "new_window",
|
|
51
|
-
link: "https://salesforce-external.slack.com/archives/C05HJK4PGJV",
|
|
52
|
-
text: "Join Slack",
|
|
53
|
-
variant: "custom"
|
|
54
|
-
},
|
|
55
|
-
secondaryActionHtml:
|
|
56
|
-
'<span class="dx-text-display-7">Ready to jump in?</span>',
|
|
57
|
-
showStepNumber: "true",
|
|
58
|
-
stepTitle: "Your Registration is Confirmed"
|
|
59
|
-
}
|
|
60
|
-
];
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { LightningElement, track } from "lwc";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* This is a helper class for when you want your LWC component to have state
|
|
5
|
-
* that is automatically tracked _along with_ its previous state, in a React-
|
|
6
|
-
* like fashion, so that you can compare current state with previous state
|
|
7
|
-
* after a render (like React's `commponentDidUpdate`). One benefit of doing
|
|
8
|
-
* things this way is that you can put all of your reactions to state changes
|
|
9
|
-
* in one place, in `renderedCallback`, rather than having them in various
|
|
10
|
-
* places throughout the component.
|
|
11
|
-
*
|
|
12
|
-
* The API consists in `this.prevState`, `this.state`, and `this.setState`.
|
|
13
|
-
*
|
|
14
|
-
* Usage:
|
|
15
|
-
*
|
|
16
|
-
* ```
|
|
17
|
-
* type MyState = {
|
|
18
|
-
* isFetchingContent: boolean;
|
|
19
|
-
* };
|
|
20
|
-
*
|
|
21
|
-
* class MyFetchingComponent extends LightningElementWithState<MyState> {
|
|
22
|
-
* constructor() {
|
|
23
|
-
* // `this.state` can only be initialized once
|
|
24
|
-
* this.state = {
|
|
25
|
-
* isFetchingContent: false
|
|
26
|
-
* };
|
|
27
|
-
* }
|
|
28
|
-
*
|
|
29
|
-
* // Queued for execution whenever a `setState` call completes
|
|
30
|
-
* renderedCallback() {
|
|
31
|
-
* if (this.prevState.isFetchingContent && !this.state.isFetchingContent) {
|
|
32
|
-
* // Do something knowing that we just finished fetching.
|
|
33
|
-
* notifyFetchSuccessful();
|
|
34
|
-
* }
|
|
35
|
-
* }
|
|
36
|
-
*
|
|
37
|
-
* fetchSomething() {
|
|
38
|
-
* this.setState({
|
|
39
|
-
* isFetchingContent: true
|
|
40
|
-
* });
|
|
41
|
-
*
|
|
42
|
-
* fetch(whatever).then(() => {
|
|
43
|
-
* this.setState({
|
|
44
|
-
* isFetching: false
|
|
45
|
-
* }
|
|
46
|
-
* });
|
|
47
|
-
* }
|
|
48
|
-
* }
|
|
49
|
-
* ```
|
|
50
|
-
*/
|
|
51
|
-
export abstract class LightningElementWithState<
|
|
52
|
-
T extends { [key: string]: unknown }
|
|
53
|
-
> extends LightningElement {
|
|
54
|
-
private _prevState = {} as T;
|
|
55
|
-
@track private _state = {} as T;
|
|
56
|
-
|
|
57
|
-
private _didInitializeState = false;
|
|
58
|
-
|
|
59
|
-
protected get prevState(): T {
|
|
60
|
-
return Object.freeze({
|
|
61
|
-
...this._prevState
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
protected get state(): T {
|
|
66
|
-
return Object.freeze({
|
|
67
|
-
...this._state
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
protected set state(initialState: T) {
|
|
72
|
-
if (!this._didInitializeState) {
|
|
73
|
-
this._state = {
|
|
74
|
-
...initialState
|
|
75
|
-
};
|
|
76
|
-
this._didInitializeState = true;
|
|
77
|
-
} else {
|
|
78
|
-
throw new Error(
|
|
79
|
-
"To mutate state after initialization, use `this.setState`."
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
protected setState = (state: Partial<T>): void => {
|
|
85
|
-
this._prevState = {
|
|
86
|
-
...this._state
|
|
87
|
-
};
|
|
88
|
-
this._state = {
|
|
89
|
-
...this._state,
|
|
90
|
-
...state
|
|
91
|
-
};
|
|
92
|
-
};
|
|
93
|
-
}
|