@salesforcedevs/docs-components 1.17.0-hack-alpha3 → 1.17.0-hack-alpha5
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 +1 -1
- package/src/modules/doc/commentPopup/README.md +212 -0
- package/src/modules/doc/commentPopup/commentDevHelper.ts +152 -0
- package/src/modules/doc/commentPopup/commentPopup.css +91 -0
- package/src/modules/doc/commentPopup/commentPopup.html +20 -1
- package/src/modules/doc/commentPopup/commentPopup.ts +230 -29
- package/src/modules/doc/commentPopup/commentUtils.ts +250 -0
- package/src/modules/doc/contentLayout/contentLayout.html +0 -1
- package/src/modules/doc/heading/heading.css +12 -382
- package/src/modules/doc/heading/heading.html +28 -150
- package/src/modules/doc/heading/heading.ts +5 -205
- package/src/modules/doc/lwcContentLayout/lwcContentLayout.html +0 -1
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
import { LightningElement, api
|
|
2
|
-
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
3
|
-
|
|
4
|
-
interface Comment {
|
|
5
|
-
email: string;
|
|
6
|
-
comment: string;
|
|
7
|
-
url: string;
|
|
8
|
-
timestamp: Date;
|
|
9
|
-
}
|
|
1
|
+
import { LightningElement, api } from "lwc";
|
|
10
2
|
|
|
11
3
|
export const ariaDisplayLevels: { [key: string]: string } = {
|
|
12
4
|
"1": "4",
|
|
@@ -39,21 +31,6 @@ export default class Heading extends LightningElement {
|
|
|
39
31
|
@api emailPlaceholder = "Enter your email";
|
|
40
32
|
@api commentPlaceholder = "Enter your comment";
|
|
41
33
|
|
|
42
|
-
private _open = false;
|
|
43
|
-
@api get open() {
|
|
44
|
-
return this._open;
|
|
45
|
-
}
|
|
46
|
-
set open(value) {
|
|
47
|
-
this._open = normalizeBoolean(value);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@track private comments: Comment[] = [];
|
|
51
|
-
@track private email = "";
|
|
52
|
-
@track private comment = "";
|
|
53
|
-
@track private emailError = "";
|
|
54
|
-
@track private commentError = "";
|
|
55
|
-
@track private isSubmitting = false;
|
|
56
|
-
|
|
57
34
|
@api
|
|
58
35
|
private get ariaLevel(): string {
|
|
59
36
|
// Really Dark Magic (TM)
|
|
@@ -103,189 +80,12 @@ export default class Heading extends LightningElement {
|
|
|
103
80
|
return `dx-text-display-${this.displayLevel}`;
|
|
104
81
|
}
|
|
105
82
|
|
|
106
|
-
// Comment popup
|
|
107
|
-
get showComments() {
|
|
108
|
-
const unwrapped = JSON.parse(JSON.stringify(this.comments));
|
|
109
|
-
console.log("Comments (JSON unwrapped):", unwrapped);
|
|
110
|
-
return this.comments.length > 0;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
get commentCount() {
|
|
114
|
-
return this.comments.length;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
get showCommentCount() {
|
|
118
|
-
return this.commentCount > 0;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
get sortedComments() {
|
|
122
|
-
return [...this.comments].sort(
|
|
123
|
-
(a, b) => b.timestamp.getTime() - a.timestamp.getTime()
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
get isFormValid() {
|
|
128
|
-
return this.email.trim() !== "" && this.comment.trim() !== "";
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
get submitButtonDisabled() {
|
|
132
|
-
return !this.isFormValid || this.isSubmitting;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
get formattedComments() {
|
|
136
|
-
return this.sortedComments.map((comment) => ({
|
|
137
|
-
...comment,
|
|
138
|
-
formattedTimestamp: this.formatTimestamp(comment.timestamp),
|
|
139
|
-
maskedEmail: this.maskEmail(comment.email)
|
|
140
|
-
}));
|
|
141
|
-
}
|
|
142
|
-
|
|
83
|
+
// Comment popup computed properties
|
|
143
84
|
get hasCommentPopup() {
|
|
144
|
-
return this.
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// Comment popup handlers
|
|
148
|
-
handleIconClick() {
|
|
149
|
-
this._open = !this._open;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
handleEmailChange(event: Event) {
|
|
153
|
-
this.email = (event.target as HTMLInputElement).value;
|
|
154
|
-
this.emailError = "";
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
handleCommentChange(event: Event) {
|
|
158
|
-
this.comment = (event.target as HTMLTextAreaElement).value;
|
|
159
|
-
this.commentError = "";
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
handleSubmit() {
|
|
163
|
-
if (!this.validateForm()) {
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
this.isSubmitting = true;
|
|
168
|
-
|
|
169
|
-
// Simulate API call
|
|
170
|
-
setTimeout(() => {
|
|
171
|
-
this.addComment();
|
|
172
|
-
this.resetForm();
|
|
173
|
-
this.isSubmitting = false;
|
|
174
|
-
}, 500);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
private validateForm(): boolean {
|
|
178
|
-
let isValid = true;
|
|
179
|
-
|
|
180
|
-
if (!this.email.trim()) {
|
|
181
|
-
this.emailError = "Email is required";
|
|
182
|
-
isValid = false;
|
|
183
|
-
} else if (!this.isValidEmail(this.email)) {
|
|
184
|
-
this.emailError = "Please enter a valid email address";
|
|
185
|
-
isValid = false;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (!this.comment.trim()) {
|
|
189
|
-
this.commentError = "Comment is required";
|
|
190
|
-
isValid = false;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return isValid;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
private isValidEmail(email: string): boolean {
|
|
197
|
-
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
198
|
-
return emailRegex.test(email);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private addComment() {
|
|
202
|
-
const newComment: Comment = {
|
|
203
|
-
email: this.email.trim(),
|
|
204
|
-
comment: this.comment.trim(),
|
|
205
|
-
url: window.location.href,
|
|
206
|
-
timestamp: new Date()
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
this.comments = [newComment, ...this.comments];
|
|
210
|
-
|
|
211
|
-
// Dispatch custom event
|
|
212
|
-
this.dispatchEvent(
|
|
213
|
-
new CustomEvent("commentadded", {
|
|
214
|
-
detail: newComment
|
|
215
|
-
})
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
private resetForm() {
|
|
220
|
-
this.email = "";
|
|
221
|
-
this.comment = "";
|
|
222
|
-
this.emailError = "";
|
|
223
|
-
this.commentError = "";
|
|
224
|
-
|
|
225
|
-
// Force DOM update by accessing the form elements
|
|
226
|
-
const emailInput = this.template.querySelector(
|
|
227
|
-
"#email-input"
|
|
228
|
-
) as HTMLInputElement;
|
|
229
|
-
const commentInput = this.template.querySelector(
|
|
230
|
-
"#comment-input"
|
|
231
|
-
) as HTMLTextAreaElement;
|
|
232
|
-
|
|
233
|
-
if (emailInput) {
|
|
234
|
-
emailInput.value = "";
|
|
235
|
-
}
|
|
236
|
-
if (commentInput) {
|
|
237
|
-
commentInput.value = "";
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
handleClose() {
|
|
242
|
-
this._open = false;
|
|
243
|
-
this.resetForm();
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
handleOverlayClick(event: Event) {
|
|
247
|
-
if (event.target === event.currentTarget) {
|
|
248
|
-
this.handleClose();
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
handleKeyDown(event: KeyboardEvent) {
|
|
253
|
-
if (event.key === "Escape") {
|
|
254
|
-
this.handleClose();
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
connectedCallback() {
|
|
259
|
-
document.addEventListener("keydown", this.handleKeyDown.bind(this));
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
disconnectedCallback() {
|
|
263
|
-
document.removeEventListener("keydown", this.handleKeyDown.bind(this));
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
private formatTimestamp(timestamp: Date): string {
|
|
267
|
-
const now = new Date();
|
|
268
|
-
const diff = now.getTime() - timestamp.getTime();
|
|
269
|
-
const minutes = Math.floor(diff / 60000);
|
|
270
|
-
const hours = Math.floor(diff / 3600000);
|
|
271
|
-
const days = Math.floor(diff / 86400000);
|
|
272
|
-
|
|
273
|
-
if (minutes < 1) {
|
|
274
|
-
return "Just now";
|
|
275
|
-
} else if (minutes < 60) {
|
|
276
|
-
return `${minutes} minute${minutes > 1 ? "s" : ""} ago`;
|
|
277
|
-
} else if (hours < 24) {
|
|
278
|
-
return `${hours} hour${hours > 1 ? "s" : ""} ago`;
|
|
279
|
-
}
|
|
280
|
-
return `${days} day${days > 1 ? "s" : ""} ago`;
|
|
85
|
+
return this.currentBranch !== undefined;
|
|
281
86
|
}
|
|
282
87
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
const maskedLocal =
|
|
286
|
-
localPart.length > 2
|
|
287
|
-
? localPart.substring(0, 2) + "*".repeat(localPart.length - 2)
|
|
288
|
-
: localPart;
|
|
289
|
-
return `${maskedLocal}@${domain}`;
|
|
88
|
+
get headingTitle() {
|
|
89
|
+
return this.header;
|
|
290
90
|
}
|
|
291
91
|
}
|